History log of /openbsd-current/usr.sbin/smtpd/smtpd.h
Revision (<<< Hide revision tags) (Show revision tags >>>) Date Author Comments
# 1.686 02-Jun-2024 jsg

remove prototypes with no matching function
leave prototypes with functions in OpenSMTPD-extras
ok op@


# 1.685 28-May-2024 op

actually honour the services supported by the proc tables

ok gilles@


# 1.684 07-May-2024 op

change the smtpd table protocol

Using imsg for the "proc" table (external programs) has proven quite
painful in practice since a lot of smtpd internals (structs, enums,
etc..) have to be kept in sync with the various tables implementations.

Instead, a filter-like protocol for tables decouples the implementations
and allows to write and test tables easily.

The new text-based transport protocol is documented in the (added)
smtpd-tables(7) manpage.

The old imsg protocol is no longer supported and existing tables have to
be converted. In particular, users of opensmtpd-extras tables will need
install the new opensmtpd-table-* packages.

With lots of suggestions and improvements from gilles and a tweak
from Philipp (philipp+openbsd [at] bureaucracy [dot] de), thanks!

ok gilles


Revision tags: OPENBSD_7_5_BASE
# 1.683 02-Mar-2024 op

bump version to 7.5.0


# 1.682 11-Feb-2024 op

unify smtpd and makemap table parser

These are supposed to parse the same file format but have subtle
difference in the handling of comments, continuation lines and escaping.

Converge both to the simpler smtpd parser which doesn't handle
continuation lines nor escaping, and support comments only at the start
of the line.

improvements and ok millert@


# 1.681 02-Feb-2024 gilles

there's no good reason to allow smtpd to execute custom command set by root
in a .forward file so disallow custom commands and file reading, only allow
setting forward addresses and users.

as root is no longer allowed to run any MDA but mbox, we can be stricter on
the setup of the MDA process and refuse to exec anything that's not an mbox
dispatcher.

tested by op@ who edited a root envelope to simulate an exploit injecting a
custom command in a root envelope, smtpd refused to exec.

ok millert@ and op@


# 1.680 03-Jan-2024 op

relax ORCPT syntax validation

We expected the ORCPT parameter to be a valid rfc822 address. This is
wrong on multiple levels:

- any other IANA-registered "addr-type" can be used
- the parameter may be encoded and we didn't decode it prior validation
- RFC3461 explicitly states that "[..] the address associated with the
ORCPT keyword is NOT constrained to conform to the syntax rules for
that 'addr-type'".

Instead, just validate the xtext and preserve the ORCPT value as-is.

Issue originally reported by Tim Kuijsten, Tassilo Philipp and others.

ok millert@


# 1.679 08-Nov-2023 op

RFC 7505 ("Null MX") handling

mail delivery will not be attempted if a domain advertises a single MX
record with preference 0 and a zero-length label.

based on an initial diff from Philipp (philipp+openbsd [at] bureaucracy
[dot] de), thanks!

ok jung@


Revision tags: OPENBSD_7_4_BASE
# 1.678 29-Sep-2023 op

bump version to 7.4.0


# 1.677 17-Jun-2023 op

bump version to 7.3.0


# 1.676 31-May-2023 op

add missing include of time.h

spotted after a report on OpenSMTPD-portable. While here include
sys/time.h in smtpd.h, as noted in event_init(3), since it includes
event.h.

ok millert@


# 1.675 25-May-2023 op

remove two unused defines

last PROC_COUNT use was removed with the switch to fork+exec by eric@ in
2016, CA_FILE with the removal of cert.c two years ago.

ok tb@, kn@


Revision tags: OPENBSD_7_1_BASE OPENBSD_7_2_BASE OPENBSD_7_3_BASE
# 1.674 18-Feb-2022 millert

Revert changes to use the new libtls signer api
There are bugs in the new libtls signer that can lead to a crash.
OK tb@ jsing@


# 1.673 12-Feb-2022 eric

use new libtls signer api

ok tb@


# 1.672 10-Feb-2022 millert

Do not verify the cert or CA for a relay using opportunistic TLS.
If a relay is not explicitly configured to use TLS but the remote
side supports STARTTLS, we will try to use it. However, in this
case we should not verify the cert or CA (which may be self-signed).
This restores the relay behavior before the switch to libtls was made.
There is no change if the relay is explicitly configured to use TLS.
OK eric@


Revision tags: OPENBSD_7_0_BASE
# 1.671 22-Sep-2021 eric

bump version to 7.0.0


# 1.670 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.669 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.668 21-Apr-2021 eric

unplug unused certificate verification code, now that this is done by libtls.

ok tb@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.685 28-May-2024 op

actually honour the services supported by the proc tables

ok gilles@


# 1.684 07-May-2024 op

change the smtpd table protocol

Using imsg for the "proc" table (external programs) has proven quite
painful in practice since a lot of smtpd internals (structs, enums,
etc..) have to be kept in sync with the various tables implementations.

Instead, a filter-like protocol for tables decouples the implementations
and allows to write and test tables easily.

The new text-based transport protocol is documented in the (added)
smtpd-tables(7) manpage.

The old imsg protocol is no longer supported and existing tables have to
be converted. In particular, users of opensmtpd-extras tables will need
install the new opensmtpd-table-* packages.

With lots of suggestions and improvements from gilles and a tweak
from Philipp (philipp+openbsd [at] bureaucracy [dot] de), thanks!

ok gilles


Revision tags: OPENBSD_7_5_BASE
# 1.683 02-Mar-2024 op

bump version to 7.5.0


# 1.682 11-Feb-2024 op

unify smtpd and makemap table parser

These are supposed to parse the same file format but have subtle
difference in the handling of comments, continuation lines and escaping.

Converge both to the simpler smtpd parser which doesn't handle
continuation lines nor escaping, and support comments only at the start
of the line.

improvements and ok millert@


# 1.681 02-Feb-2024 gilles

there's no good reason to allow smtpd to execute custom command set by root
in a .forward file so disallow custom commands and file reading, only allow
setting forward addresses and users.

as root is no longer allowed to run any MDA but mbox, we can be stricter on
the setup of the MDA process and refuse to exec anything that's not an mbox
dispatcher.

tested by op@ who edited a root envelope to simulate an exploit injecting a
custom command in a root envelope, smtpd refused to exec.

ok millert@ and op@


# 1.680 03-Jan-2024 op

relax ORCPT syntax validation

We expected the ORCPT parameter to be a valid rfc822 address. This is
wrong on multiple levels:

- any other IANA-registered "addr-type" can be used
- the parameter may be encoded and we didn't decode it prior validation
- RFC3461 explicitly states that "[..] the address associated with the
ORCPT keyword is NOT constrained to conform to the syntax rules for
that 'addr-type'".

Instead, just validate the xtext and preserve the ORCPT value as-is.

Issue originally reported by Tim Kuijsten, Tassilo Philipp and others.

ok millert@


# 1.679 08-Nov-2023 op

RFC 7505 ("Null MX") handling

mail delivery will not be attempted if a domain advertises a single MX
record with preference 0 and a zero-length label.

based on an initial diff from Philipp (philipp+openbsd [at] bureaucracy
[dot] de), thanks!

ok jung@


Revision tags: OPENBSD_7_4_BASE
# 1.678 29-Sep-2023 op

bump version to 7.4.0


# 1.677 17-Jun-2023 op

bump version to 7.3.0


# 1.676 31-May-2023 op

add missing include of time.h

spotted after a report on OpenSMTPD-portable. While here include
sys/time.h in smtpd.h, as noted in event_init(3), since it includes
event.h.

ok millert@


# 1.675 25-May-2023 op

remove two unused defines

last PROC_COUNT use was removed with the switch to fork+exec by eric@ in
2016, CA_FILE with the removal of cert.c two years ago.

ok tb@, kn@


Revision tags: OPENBSD_7_1_BASE OPENBSD_7_2_BASE OPENBSD_7_3_BASE
# 1.674 18-Feb-2022 millert

Revert changes to use the new libtls signer api
There are bugs in the new libtls signer that can lead to a crash.
OK tb@ jsing@


# 1.673 12-Feb-2022 eric

use new libtls signer api

ok tb@


# 1.672 10-Feb-2022 millert

Do not verify the cert or CA for a relay using opportunistic TLS.
If a relay is not explicitly configured to use TLS but the remote
side supports STARTTLS, we will try to use it. However, in this
case we should not verify the cert or CA (which may be self-signed).
This restores the relay behavior before the switch to libtls was made.
There is no change if the relay is explicitly configured to use TLS.
OK eric@


Revision tags: OPENBSD_7_0_BASE
# 1.671 22-Sep-2021 eric

bump version to 7.0.0


# 1.670 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.669 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.668 21-Apr-2021 eric

unplug unused certificate verification code, now that this is done by libtls.

ok tb@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.684 07-May-2024 op

change the smtpd table protocol

Using imsg for the "proc" table (external programs) has proven quite
painful in practice since a lot of smtpd internals (structs, enums,
etc..) have to be kept in sync with the various tables implementations.

Instead, a filter-like protocol for tables decouples the implementations
and allows to write and test tables easily.

The new text-based transport protocol is documented in the (added)
smtpd-tables(7) manpage.

The old imsg protocol is no longer supported and existing tables have to
be converted. In particular, users of opensmtpd-extras tables will need
install the new opensmtpd-table-* packages.

With lots of suggestions and improvements from gilles and a tweak
from Philipp (philipp+openbsd [at] bureaucracy [dot] de), thanks!

ok gilles


Revision tags: OPENBSD_7_5_BASE
# 1.683 02-Mar-2024 op

bump version to 7.5.0


# 1.682 11-Feb-2024 op

unify smtpd and makemap table parser

These are supposed to parse the same file format but have subtle
difference in the handling of comments, continuation lines and escaping.

Converge both to the simpler smtpd parser which doesn't handle
continuation lines nor escaping, and support comments only at the start
of the line.

improvements and ok millert@


# 1.681 02-Feb-2024 gilles

there's no good reason to allow smtpd to execute custom command set by root
in a .forward file so disallow custom commands and file reading, only allow
setting forward addresses and users.

as root is no longer allowed to run any MDA but mbox, we can be stricter on
the setup of the MDA process and refuse to exec anything that's not an mbox
dispatcher.

tested by op@ who edited a root envelope to simulate an exploit injecting a
custom command in a root envelope, smtpd refused to exec.

ok millert@ and op@


# 1.680 03-Jan-2024 op

relax ORCPT syntax validation

We expected the ORCPT parameter to be a valid rfc822 address. This is
wrong on multiple levels:

- any other IANA-registered "addr-type" can be used
- the parameter may be encoded and we didn't decode it prior validation
- RFC3461 explicitly states that "[..] the address associated with the
ORCPT keyword is NOT constrained to conform to the syntax rules for
that 'addr-type'".

Instead, just validate the xtext and preserve the ORCPT value as-is.

Issue originally reported by Tim Kuijsten, Tassilo Philipp and others.

ok millert@


# 1.679 08-Nov-2023 op

RFC 7505 ("Null MX") handling

mail delivery will not be attempted if a domain advertises a single MX
record with preference 0 and a zero-length label.

based on an initial diff from Philipp (philipp+openbsd [at] bureaucracy
[dot] de), thanks!

ok jung@


Revision tags: OPENBSD_7_4_BASE
# 1.678 29-Sep-2023 op

bump version to 7.4.0


# 1.677 17-Jun-2023 op

bump version to 7.3.0


# 1.676 31-May-2023 op

add missing include of time.h

spotted after a report on OpenSMTPD-portable. While here include
sys/time.h in smtpd.h, as noted in event_init(3), since it includes
event.h.

ok millert@


# 1.675 25-May-2023 op

remove two unused defines

last PROC_COUNT use was removed with the switch to fork+exec by eric@ in
2016, CA_FILE with the removal of cert.c two years ago.

ok tb@, kn@


Revision tags: OPENBSD_7_1_BASE OPENBSD_7_2_BASE OPENBSD_7_3_BASE
# 1.674 18-Feb-2022 millert

Revert changes to use the new libtls signer api
There are bugs in the new libtls signer that can lead to a crash.
OK tb@ jsing@


# 1.673 12-Feb-2022 eric

use new libtls signer api

ok tb@


# 1.672 10-Feb-2022 millert

Do not verify the cert or CA for a relay using opportunistic TLS.
If a relay is not explicitly configured to use TLS but the remote
side supports STARTTLS, we will try to use it. However, in this
case we should not verify the cert or CA (which may be self-signed).
This restores the relay behavior before the switch to libtls was made.
There is no change if the relay is explicitly configured to use TLS.
OK eric@


Revision tags: OPENBSD_7_0_BASE
# 1.671 22-Sep-2021 eric

bump version to 7.0.0


# 1.670 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.669 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.668 21-Apr-2021 eric

unplug unused certificate verification code, now that this is done by libtls.

ok tb@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.683 02-Mar-2024 op

bump version to 7.5.0


# 1.682 11-Feb-2024 op

unify smtpd and makemap table parser

These are supposed to parse the same file format but have subtle
difference in the handling of comments, continuation lines and escaping.

Converge both to the simpler smtpd parser which doesn't handle
continuation lines nor escaping, and support comments only at the start
of the line.

improvements and ok millert@


# 1.681 02-Feb-2024 gilles

there's no good reason to allow smtpd to execute custom command set by root
in a .forward file so disallow custom commands and file reading, only allow
setting forward addresses and users.

as root is no longer allowed to run any MDA but mbox, we can be stricter on
the setup of the MDA process and refuse to exec anything that's not an mbox
dispatcher.

tested by op@ who edited a root envelope to simulate an exploit injecting a
custom command in a root envelope, smtpd refused to exec.

ok millert@ and op@


# 1.680 03-Jan-2024 op

relax ORCPT syntax validation

We expected the ORCPT parameter to be a valid rfc822 address. This is
wrong on multiple levels:

- any other IANA-registered "addr-type" can be used
- the parameter may be encoded and we didn't decode it prior validation
- RFC3461 explicitly states that "[..] the address associated with the
ORCPT keyword is NOT constrained to conform to the syntax rules for
that 'addr-type'".

Instead, just validate the xtext and preserve the ORCPT value as-is.

Issue originally reported by Tim Kuijsten, Tassilo Philipp and others.

ok millert@


# 1.679 08-Nov-2023 op

RFC 7505 ("Null MX") handling

mail delivery will not be attempted if a domain advertises a single MX
record with preference 0 and a zero-length label.

based on an initial diff from Philipp (philipp+openbsd [at] bureaucracy
[dot] de), thanks!

ok jung@


Revision tags: OPENBSD_7_4_BASE
# 1.678 29-Sep-2023 op

bump version to 7.4.0


# 1.677 17-Jun-2023 op

bump version to 7.3.0


# 1.676 31-May-2023 op

add missing include of time.h

spotted after a report on OpenSMTPD-portable. While here include
sys/time.h in smtpd.h, as noted in event_init(3), since it includes
event.h.

ok millert@


# 1.675 25-May-2023 op

remove two unused defines

last PROC_COUNT use was removed with the switch to fork+exec by eric@ in
2016, CA_FILE with the removal of cert.c two years ago.

ok tb@, kn@


Revision tags: OPENBSD_7_1_BASE OPENBSD_7_2_BASE OPENBSD_7_3_BASE
# 1.674 18-Feb-2022 millert

Revert changes to use the new libtls signer api
There are bugs in the new libtls signer that can lead to a crash.
OK tb@ jsing@


# 1.673 12-Feb-2022 eric

use new libtls signer api

ok tb@


# 1.672 10-Feb-2022 millert

Do not verify the cert or CA for a relay using opportunistic TLS.
If a relay is not explicitly configured to use TLS but the remote
side supports STARTTLS, we will try to use it. However, in this
case we should not verify the cert or CA (which may be self-signed).
This restores the relay behavior before the switch to libtls was made.
There is no change if the relay is explicitly configured to use TLS.
OK eric@


Revision tags: OPENBSD_7_0_BASE
# 1.671 22-Sep-2021 eric

bump version to 7.0.0


# 1.670 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.669 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.668 21-Apr-2021 eric

unplug unused certificate verification code, now that this is done by libtls.

ok tb@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.682 11-Feb-2024 op

unify smtpd and makemap table parser

These are supposed to parse the same file format but have subtle
difference in the handling of comments, continuation lines and escaping.

Converge both to the simpler smtpd parser which doesn't handle
continuation lines nor escaping, and support comments only at the start
of the line.

improvements and ok millert@


# 1.681 02-Feb-2024 gilles

there's no good reason to allow smtpd to execute custom command set by root
in a .forward file so disallow custom commands and file reading, only allow
setting forward addresses and users.

as root is no longer allowed to run any MDA but mbox, we can be stricter on
the setup of the MDA process and refuse to exec anything that's not an mbox
dispatcher.

tested by op@ who edited a root envelope to simulate an exploit injecting a
custom command in a root envelope, smtpd refused to exec.

ok millert@ and op@


# 1.680 03-Jan-2024 op

relax ORCPT syntax validation

We expected the ORCPT parameter to be a valid rfc822 address. This is
wrong on multiple levels:

- any other IANA-registered "addr-type" can be used
- the parameter may be encoded and we didn't decode it prior validation
- RFC3461 explicitly states that "[..] the address associated with the
ORCPT keyword is NOT constrained to conform to the syntax rules for
that 'addr-type'".

Instead, just validate the xtext and preserve the ORCPT value as-is.

Issue originally reported by Tim Kuijsten, Tassilo Philipp and others.

ok millert@


# 1.679 08-Nov-2023 op

RFC 7505 ("Null MX") handling

mail delivery will not be attempted if a domain advertises a single MX
record with preference 0 and a zero-length label.

based on an initial diff from Philipp (philipp+openbsd [at] bureaucracy
[dot] de), thanks!

ok jung@


Revision tags: OPENBSD_7_4_BASE
# 1.678 29-Sep-2023 op

bump version to 7.4.0


# 1.677 17-Jun-2023 op

bump version to 7.3.0


# 1.676 31-May-2023 op

add missing include of time.h

spotted after a report on OpenSMTPD-portable. While here include
sys/time.h in smtpd.h, as noted in event_init(3), since it includes
event.h.

ok millert@


# 1.675 25-May-2023 op

remove two unused defines

last PROC_COUNT use was removed with the switch to fork+exec by eric@ in
2016, CA_FILE with the removal of cert.c two years ago.

ok tb@, kn@


Revision tags: OPENBSD_7_1_BASE OPENBSD_7_2_BASE OPENBSD_7_3_BASE
# 1.674 18-Feb-2022 millert

Revert changes to use the new libtls signer api
There are bugs in the new libtls signer that can lead to a crash.
OK tb@ jsing@


# 1.673 12-Feb-2022 eric

use new libtls signer api

ok tb@


# 1.672 10-Feb-2022 millert

Do not verify the cert or CA for a relay using opportunistic TLS.
If a relay is not explicitly configured to use TLS but the remote
side supports STARTTLS, we will try to use it. However, in this
case we should not verify the cert or CA (which may be self-signed).
This restores the relay behavior before the switch to libtls was made.
There is no change if the relay is explicitly configured to use TLS.
OK eric@


Revision tags: OPENBSD_7_0_BASE
# 1.671 22-Sep-2021 eric

bump version to 7.0.0


# 1.670 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.669 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.668 21-Apr-2021 eric

unplug unused certificate verification code, now that this is done by libtls.

ok tb@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.681 02-Feb-2024 gilles

there's no good reason to allow smtpd to execute custom command set by root
in a .forward file so disallow custom commands and file reading, only allow
setting forward addresses and users.

as root is no longer allowed to run any MDA but mbox, we can be stricter on
the setup of the MDA process and refuse to exec anything that's not an mbox
dispatcher.

tested by op@ who edited a root envelope to simulate an exploit injecting a
custom command in a root envelope, smtpd refused to exec.

ok millert@ and op@


# 1.680 03-Jan-2024 op

relax ORCPT syntax validation

We expected the ORCPT parameter to be a valid rfc822 address. This is
wrong on multiple levels:

- any other IANA-registered "addr-type" can be used
- the parameter may be encoded and we didn't decode it prior validation
- RFC3461 explicitly states that "[..] the address associated with the
ORCPT keyword is NOT constrained to conform to the syntax rules for
that 'addr-type'".

Instead, just validate the xtext and preserve the ORCPT value as-is.

Issue originally reported by Tim Kuijsten, Tassilo Philipp and others.

ok millert@


# 1.679 08-Nov-2023 op

RFC 7505 ("Null MX") handling

mail delivery will not be attempted if a domain advertises a single MX
record with preference 0 and a zero-length label.

based on an initial diff from Philipp (philipp+openbsd [at] bureaucracy
[dot] de), thanks!

ok jung@


Revision tags: OPENBSD_7_4_BASE
# 1.678 29-Sep-2023 op

bump version to 7.4.0


# 1.677 17-Jun-2023 op

bump version to 7.3.0


# 1.676 31-May-2023 op

add missing include of time.h

spotted after a report on OpenSMTPD-portable. While here include
sys/time.h in smtpd.h, as noted in event_init(3), since it includes
event.h.

ok millert@


# 1.675 25-May-2023 op

remove two unused defines

last PROC_COUNT use was removed with the switch to fork+exec by eric@ in
2016, CA_FILE with the removal of cert.c two years ago.

ok tb@, kn@


Revision tags: OPENBSD_7_1_BASE OPENBSD_7_2_BASE OPENBSD_7_3_BASE
# 1.674 18-Feb-2022 millert

Revert changes to use the new libtls signer api
There are bugs in the new libtls signer that can lead to a crash.
OK tb@ jsing@


# 1.673 12-Feb-2022 eric

use new libtls signer api

ok tb@


# 1.672 10-Feb-2022 millert

Do not verify the cert or CA for a relay using opportunistic TLS.
If a relay is not explicitly configured to use TLS but the remote
side supports STARTTLS, we will try to use it. However, in this
case we should not verify the cert or CA (which may be self-signed).
This restores the relay behavior before the switch to libtls was made.
There is no change if the relay is explicitly configured to use TLS.
OK eric@


Revision tags: OPENBSD_7_0_BASE
# 1.671 22-Sep-2021 eric

bump version to 7.0.0


# 1.670 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.669 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.668 21-Apr-2021 eric

unplug unused certificate verification code, now that this is done by libtls.

ok tb@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.680 03-Jan-2024 op

relax ORCPT syntax validation

We expected the ORCPT parameter to be a valid rfc822 address. This is
wrong on multiple levels:

- any other IANA-registered "addr-type" can be used
- the parameter may be encoded and we didn't decode it prior validation
- RFC3461 explicitly states that "[..] the address associated with the
ORCPT keyword is NOT constrained to conform to the syntax rules for
that 'addr-type'".

Instead, just validate the xtext and preserve the ORCPT value as-is.

Issue originally reported by Tim Kuijsten, Tassilo Philipp and others.

ok millert@


# 1.679 08-Nov-2023 op

RFC 7505 ("Null MX") handling

mail delivery will not be attempted if a domain advertises a single MX
record with preference 0 and a zero-length label.

based on an initial diff from Philipp (philipp+openbsd [at] bureaucracy
[dot] de), thanks!

ok jung@


Revision tags: OPENBSD_7_4_BASE
# 1.678 29-Sep-2023 op

bump version to 7.4.0


# 1.677 17-Jun-2023 op

bump version to 7.3.0


# 1.676 31-May-2023 op

add missing include of time.h

spotted after a report on OpenSMTPD-portable. While here include
sys/time.h in smtpd.h, as noted in event_init(3), since it includes
event.h.

ok millert@


# 1.675 25-May-2023 op

remove two unused defines

last PROC_COUNT use was removed with the switch to fork+exec by eric@ in
2016, CA_FILE with the removal of cert.c two years ago.

ok tb@, kn@


Revision tags: OPENBSD_7_1_BASE OPENBSD_7_2_BASE OPENBSD_7_3_BASE
# 1.674 18-Feb-2022 millert

Revert changes to use the new libtls signer api
There are bugs in the new libtls signer that can lead to a crash.
OK tb@ jsing@


# 1.673 12-Feb-2022 eric

use new libtls signer api

ok tb@


# 1.672 10-Feb-2022 millert

Do not verify the cert or CA for a relay using opportunistic TLS.
If a relay is not explicitly configured to use TLS but the remote
side supports STARTTLS, we will try to use it. However, in this
case we should not verify the cert or CA (which may be self-signed).
This restores the relay behavior before the switch to libtls was made.
There is no change if the relay is explicitly configured to use TLS.
OK eric@


Revision tags: OPENBSD_7_0_BASE
# 1.671 22-Sep-2021 eric

bump version to 7.0.0


# 1.670 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.669 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.668 21-Apr-2021 eric

unplug unused certificate verification code, now that this is done by libtls.

ok tb@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.679 08-Nov-2023 op

RFC 7505 ("Null MX") handling

mail delivery will not be attempted if a domain advertises a single MX
record with preference 0 and a zero-length label.

based on an initial diff from Philipp (philipp+openbsd [at] bureaucracy
[dot] de), thanks!

ok jung@


Revision tags: OPENBSD_7_4_BASE
# 1.678 29-Sep-2023 op

bump version to 7.4.0


# 1.677 17-Jun-2023 op

bump version to 7.3.0


# 1.676 31-May-2023 op

add missing include of time.h

spotted after a report on OpenSMTPD-portable. While here include
sys/time.h in smtpd.h, as noted in event_init(3), since it includes
event.h.

ok millert@


# 1.675 25-May-2023 op

remove two unused defines

last PROC_COUNT use was removed with the switch to fork+exec by eric@ in
2016, CA_FILE with the removal of cert.c two years ago.

ok tb@, kn@


Revision tags: OPENBSD_7_1_BASE OPENBSD_7_2_BASE OPENBSD_7_3_BASE
# 1.674 18-Feb-2022 millert

Revert changes to use the new libtls signer api
There are bugs in the new libtls signer that can lead to a crash.
OK tb@ jsing@


# 1.673 12-Feb-2022 eric

use new libtls signer api

ok tb@


# 1.672 10-Feb-2022 millert

Do not verify the cert or CA for a relay using opportunistic TLS.
If a relay is not explicitly configured to use TLS but the remote
side supports STARTTLS, we will try to use it. However, in this
case we should not verify the cert or CA (which may be self-signed).
This restores the relay behavior before the switch to libtls was made.
There is no change if the relay is explicitly configured to use TLS.
OK eric@


Revision tags: OPENBSD_7_0_BASE
# 1.671 22-Sep-2021 eric

bump version to 7.0.0


# 1.670 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.669 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.668 21-Apr-2021 eric

unplug unused certificate verification code, now that this is done by libtls.

ok tb@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.678 29-Sep-2023 op

bump version to 7.4.0


# 1.677 17-Jun-2023 op

bump version to 7.3.0


# 1.676 31-May-2023 op

add missing include of time.h

spotted after a report on OpenSMTPD-portable. While here include
sys/time.h in smtpd.h, as noted in event_init(3), since it includes
event.h.

ok millert@


# 1.675 25-May-2023 op

remove two unused defines

last PROC_COUNT use was removed with the switch to fork+exec by eric@ in
2016, CA_FILE with the removal of cert.c two years ago.

ok tb@, kn@


Revision tags: OPENBSD_7_1_BASE OPENBSD_7_2_BASE OPENBSD_7_3_BASE
# 1.674 18-Feb-2022 millert

Revert changes to use the new libtls signer api
There are bugs in the new libtls signer that can lead to a crash.
OK tb@ jsing@


# 1.673 12-Feb-2022 eric

use new libtls signer api

ok tb@


# 1.672 10-Feb-2022 millert

Do not verify the cert or CA for a relay using opportunistic TLS.
If a relay is not explicitly configured to use TLS but the remote
side supports STARTTLS, we will try to use it. However, in this
case we should not verify the cert or CA (which may be self-signed).
This restores the relay behavior before the switch to libtls was made.
There is no change if the relay is explicitly configured to use TLS.
OK eric@


Revision tags: OPENBSD_7_0_BASE
# 1.671 22-Sep-2021 eric

bump version to 7.0.0


# 1.670 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.669 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.668 21-Apr-2021 eric

unplug unused certificate verification code, now that this is done by libtls.

ok tb@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.677 17-Jun-2023 op

bump version to 7.3.0


# 1.676 31-May-2023 op

add missing include of time.h

spotted after a report on OpenSMTPD-portable. While here include
sys/time.h in smtpd.h, as noted in event_init(3), since it includes
event.h.

ok millert@


# 1.675 25-May-2023 op

remove two unused defines

last PROC_COUNT use was removed with the switch to fork+exec by eric@ in
2016, CA_FILE with the removal of cert.c two years ago.

ok tb@, kn@


Revision tags: OPENBSD_7_1_BASE OPENBSD_7_2_BASE OPENBSD_7_3_BASE
# 1.674 18-Feb-2022 millert

Revert changes to use the new libtls signer api
There are bugs in the new libtls signer that can lead to a crash.
OK tb@ jsing@


# 1.673 12-Feb-2022 eric

use new libtls signer api

ok tb@


# 1.672 10-Feb-2022 millert

Do not verify the cert or CA for a relay using opportunistic TLS.
If a relay is not explicitly configured to use TLS but the remote
side supports STARTTLS, we will try to use it. However, in this
case we should not verify the cert or CA (which may be self-signed).
This restores the relay behavior before the switch to libtls was made.
There is no change if the relay is explicitly configured to use TLS.
OK eric@


Revision tags: OPENBSD_7_0_BASE
# 1.671 22-Sep-2021 eric

bump version to 7.0.0


# 1.670 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.669 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.668 21-Apr-2021 eric

unplug unused certificate verification code, now that this is done by libtls.

ok tb@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.674 18-Feb-2022 millert

Revert changes to use the new libtls signer api
There are bugs in the new libtls signer that can lead to a crash.
OK tb@ jsing@


# 1.673 12-Feb-2022 eric

use new libtls signer api

ok tb@


# 1.672 10-Feb-2022 millert

Do not verify the cert or CA for a relay using opportunistic TLS.
If a relay is not explicitly configured to use TLS but the remote
side supports STARTTLS, we will try to use it. However, in this
case we should not verify the cert or CA (which may be self-signed).
This restores the relay behavior before the switch to libtls was made.
There is no change if the relay is explicitly configured to use TLS.
OK eric@


Revision tags: OPENBSD_7_0_BASE
# 1.671 22-Sep-2021 eric

bump version to 7.0.0


# 1.670 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.669 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.668 21-Apr-2021 eric

unplug unused certificate verification code, now that this is done by libtls.

ok tb@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.673 12-Feb-2022 eric

use new libtls signer api

ok tb@


# 1.672 10-Feb-2022 millert

Do not verify the cert or CA for a relay using opportunistic TLS.
If a relay is not explicitly configured to use TLS but the remote
side supports STARTTLS, we will try to use it. However, in this
case we should not verify the cert or CA (which may be self-signed).
This restores the relay behavior before the switch to libtls was made.
There is no change if the relay is explicitly configured to use TLS.
OK eric@


Revision tags: OPENBSD_7_0_BASE
# 1.671 22-Sep-2021 eric

bump version to 7.0.0


# 1.670 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.669 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.668 21-Apr-2021 eric

unplug unused certificate verification code, now that this is done by libtls.

ok tb@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.672 10-Feb-2022 millert

Do not verify the cert or CA for a relay using opportunistic TLS.
If a relay is not explicitly configured to use TLS but the remote
side supports STARTTLS, we will try to use it. However, in this
case we should not verify the cert or CA (which may be self-signed).
This restores the relay behavior before the switch to libtls was made.
There is no change if the relay is explicitly configured to use TLS.
OK eric@


Revision tags: OPENBSD_7_0_BASE
# 1.671 22-Sep-2021 eric

bump version to 7.0.0


# 1.670 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.669 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.668 21-Apr-2021 eric

unplug unused certificate verification code, now that this is done by libtls.

ok tb@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


Revision tags: OPENBSD_7_0_BASE
# 1.671 22-Sep-2021 eric

bump version to 7.0.0


# 1.670 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.669 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.668 21-Apr-2021 eric

unplug unused certificate verification code, now that this is done by libtls.

ok tb@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.670 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.669 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.668 21-Apr-2021 eric

unplug unused certificate verification code, now that this is done by libtls.

ok tb@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.669 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.668 21-Apr-2021 eric

unplug unused certificate verification code, now that this is done by libtls.

ok tb@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.668 21-Apr-2021 eric

unplug unused certificate verification code, now that this is done by libtls.

ok tb@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.667 11-Apr-2021 eric

do not build unused code and remove uneeded dependency on libm.

ok tb@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.666 10-Apr-2021 eric

bump smtpd version


# 1.665 09-Apr-2021 eric

allow to specify tls ciphers and protocols on listeners

ok tb@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.664 31-Mar-2021 eric

turn log_trace() into a macro to prevent evaluating the format string
parameters when tracing is not enabled.

ok millert@


# 1.663 31-Mar-2021 eric

allow to specify tls protocols and ciphers on relay actions

ok espie@ sthen@ tb@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.662 05-Mar-2021 eric

Start porting smtpd to libtls.

Note that it changes the way SNI works: The certificate to use is now
selected by looking at the names found in the certificates themselves,
rather than the names of the pki entries in the configuration file.
The set of certificates for a tls listener must be defined explicitly by
using the pki listener option multiple times.

ok tb@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.661 19-Jan-2021 claudio

Do the KAME embedded scope fixup in the two places where getifaddrs() is
used. With this there should be no more embedded scopes left and therefor
in6addr_to_text() can be removed. getnameinfo() will just do the right
thing now.
OK eric@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.660 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_8_BASE
# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.659 23-Sep-2020 martijn

Revert agentx support for now, we're too close to release.

requested by deraadt@


# 1.658 23-Sep-2020 martijn

Add support for agentx to smtpd.

This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from
RFC2789, but does not export the full spec. Hopefully this will expand in
the future.

People who want to use this against net-snmp (currently the only option
known to me at the time of writing) may want to add -I -mta_sendmail to the
flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.


# 1.657 16-Sep-2020 martijn

Add the admd keyword. This can be used by filters interested in the
Authentication-Results header.

OK giovanni@


Revision tags: OPENBSD_6_7_BASE
# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.656 08-Apr-2020 eric

bump smtpd version


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.655 24-Feb-2020 millert

Bump version to 6.6.4 for errata and to match -portable.


# 1.654 24-Feb-2020 millert

Fix two security vulnerabilities discovered by Qualys.
An out of bounds read in smtpd allows an attacker to inject arbitrary
commands into the envelope file which are then executed as root.
Separately, missing privilege revocation in smtpctl allows arbitrary
commands to be run with the _smtpq group.


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

branches: 1.641.2;
Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

branches: 1.621.2;
remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.653 03-Feb-2020 gilles

now that mail.local(8) relies on lockspool(1) for mailbox locking, have the
mailbox created by smtpd for mbox before privileges are dropped then we can
call mail.local(8) with the recipient privileges.

ok millert@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.652 31-Jan-2020 gilles

introduce mda_mbox() to handle mbox delivery in its own code path, and make
it use execle() since we know all parameters and don't need command line to
be parsed.

ok millert@ and jung@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.651 30-Jan-2020 solene

Bump smtpd version after recent changes

ok gilles@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.650 08-Jan-2020 gilles

allow using the session username in builtin filters when available


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.649 21-Dec-2019 gilles

add FILTER_SUBSYSTEM_SMTP_OUT to filter_subsystem enum and add filter name
to struct dispatcher_remote, this will reduce the smtp-out reporting diff


# 1.648 21-Dec-2019 gilles

do not pass rdns, fcrdns, ss_src and ss_dest with IMSG_FILTER_SMTP_BEGIN,
but gather the information from the link-connect reporting event instead.
this removes redundant code and makes it easier to prepare for smtp-out.


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.647 18-Dec-2019 gilles

give a better name to a couple functions and struct fields related to
filters, no functional change


# 1.646 18-Dec-2019 gilles

teach relay action how to do domain-based relay host, this allows declaring
a single relay action with a mapping of relay hosts per domain.

ok eric@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.645 14-Dec-2019 gilles

introduce a bypass keyword so that builtin filters can bypass processing of
a phase when a condition is met

suggested by several people including jung@, ok jung@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.644 12-Dec-2019 gilles

filter protocol has an initial handshake within which smtpd tells filters
about a few global configuration informations. this makes smtpd tell proc
filters for which subsystem they are registered allowing them to register
only events that are relevant.


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.643 25-Nov-2019 gilles

store smtp session username in envelope and allow ruleset to match specific
users or mailaddr:

match auth "gilles@openbsd.org" [...]
match auth "@openbsd.org" [...]

ok eric@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.642 03-Nov-2019 gilles

6.6.0 -> 6.6.1


Revision tags: OPENBSD_6_6_BASE
# 1.641 30-Sep-2019 martijn

Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.641 30-Sep-2019 martijn

Allow maildir and mbox MDAs to tempfail on situations that might be
resolved over time.

While here remove mkdirs component from utils.c, which isn't used anywhere.

OK gilles@, millert@


# 1.640 29-Sep-2019 gilles

SRS uses base64 encoding for the checksum, however while this is ok when we
only have MTA in the loop, some implementations like Dovecot's LMTP dislike
finding '/' in an e-mail address. Since checksum is meant to be verified at
the MX that generated the SRS encoding, use alternate rfc354 base64 encode,
swapping '/' with '_' and '+' with '-'.

ok eric@ millert@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.639 20-Sep-2019 gilles

teach smtpd how to do SRS so hosts that act as forwarders don't break SPF.
this basic implementation does SRS0/SRS1 encoding/decoding, validating time
and checksums.

with insight from semarie@, ok eric@ and millert@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.638 19-Sep-2019 gilles

unescape / and ^ in the general delivery case, they only need to be for
maildir

ok eric@


# 1.637 18-Sep-2019 eric

Implement server certificate validation in smtp(1).
Check certificate against MX name in smtpd(8) mta.

ok gilles@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.636 11-Sep-2019 martijn

Sprinkle around some __attribute__((__format__ (printf(...))).

OK gilles@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.635 06-Sep-2019 martijn

Add support for filter-reports. These allow filters to send freetext
reports to other filters/report handlers.
Builtin filters work via the new "report" keyword.
Proc filters can send reports via:
"report|<seconds.<microseconds>|smtp-in|<reqid>|<message>"
Subscribing to these reports can be done via the the "filter-report"
keyword.
The reports themselves contain the usual elements followed by:
<type>|<name>|<message>
Type can be builtin or proc.
Name is the process name for type proc and the filter name for type builtin.

OK gilles@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.634 04-Sep-2019 gilles

introduce the 'junk' builtin filter action which marks a session or
transaction as junked when a filter matches. this with the maildir
junk option allows classifying messages in Spam folder instead of
rejecting/disconnecting.

ok semarie@, eric@, martijn@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.633 28-Aug-2019 martijn

Add a link-greeting report. This allows us to get the active domain name
in use for the current request.

OK gilles@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.632 23-Aug-2019 eric

res_hnok() is too lenient wrt to acceptable domain name in mail addresses.
replace it with a valid_domainname() check that implements something closer
to RFC 5321, but still usable in real-life.

ok gilles@ millert@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.631 10-Aug-2019 gilles

this introduces experimental proxy v2 support which is fairly isolated to a
single proxy.c file, importing it to work in tree

initial work from Antoine Kaufmann <toni@famkaufmann.info>


# 1.630 10-Aug-2019 gilles

bump version


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.629 26-Jul-2019 gilles

even though RSET can be issued outside a tx, RFC states it's noop outside a
transaction so rename link-reset to tx-reset and only issue the smtp report
when a reset _actually_ has a side-effect.

note that rset is implicit on a message commit or rollback, so tx-reset get
issued even though there was no explicit RSET. the filters are MUCH simpler
to write when you don't need to track every event that can reset a tx :-)


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.628 11-Jul-2019 gilles

introduce link-auth to the smtp reporting stream so that filters may know
if a link has been authenticated successfully or not and for which user


# 1.627 11-Jul-2019 gilles

modify link-identify so it reports if HELO or EHLO was used


# 1.626 11-Jul-2019 gilles

introduce link-reset to let smtpd report resets happening in a session


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.625 27-Jun-2019 martijn

Allow filters to log information through stderr. This simplifies and
unifies the way filters need to get their logging to the right location.

Log-messages are read line by line and are logged at LOG_ERR level via
the lookup process.

OK gilles@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.624 14-Jun-2019 eric

simplify the runq interface:

- remove (unused) per-job callback
- rename runq_schedule() to runq_schedule_at() and runq_delay()
to runq_schedule()
- remove unused runq_next()

ok sunil@ gilles@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.623 13-Jun-2019 eric

extend the resolver interface to delegate res_query() calls to the lka.

ok gilles@ sunil@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.622 05-Jun-2019 gilles

a long long time ago, in a galaxy quite close actually, reyk@ introduced an
RSA privsep engine to isolate private keys in the ca process. ECDSA support
in smtpd is become a frequent request so here's an ECDSA privsep engine and
the code required for smtpd to load ECDSA certificates and use them.


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


Revision tags: OPENBSD_6_5_BASE
# 1.621 08-Apr-2019 eric

remove unused declarations

ok gilles@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.620 28-Feb-2019 eric

bump smtpd version

on behalf of gilles@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.619 30-Jan-2019 gilles

revert previous commit, i wasn't happy with it and it probably came from a
misunderstanding.


# 1.618 30-Jan-2019 gilles

don't be too strict with .forward permissions, it's ok to process it if the
group has write access, it's not ok if the world has write access.

ok eric@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.617 05-Jan-2019 gilles

revert this change, it was committed by accident


# 1.616 05-Jan-2019 gilles

introduce smtp 'timeout' reporting event to notify filters that a timeout
occured during the smtp session


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.615 28-Dec-2018 eric

introduce table_dump() and tweak format

ok gilles@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.614 28-Dec-2018 eric

remove the tag workaround for table_create() and table_find(),
now that static tables handle their updates internally.

ok gilles@


# 1.613 28-Dec-2018 eric

remove unused members in struct table


# 1.612 27-Dec-2018 gilles

extract subaddress from last resolved node, not from dest or rcpt address
which was incorrect and can lead to ambiguous cases, this will affect the
people who were using subaddresses within aliases themselves AND expected
deliveries to a maildir subdir of the recipient user.

ok eric@


# 1.611 27-Dec-2018 eric

introduce dump() and add() table methods, only implemented for static tables.

ok gilles@


# 1.610 27-Dec-2018 eric

pass the table pointer to the lookup()/fecth() methods

ok gilles@


# 1.609 27-Dec-2018 eric

change the close() method to take the table pointer

ok gilles


# 1.608 27-Dec-2018 eric

Make the backend open method return an int to report success.
The implementation is responsible for setting the handle pointer
as needed.

ok gilles@


# 1.607 26-Dec-2018 eric

reorder parameters for consistency


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.606 26-Dec-2018 eric

introduce a table_match() function to check for a key in a table

ok gilles@


# 1.605 26-Dec-2018 eric

get rid of the unused dict argument in table lookup and fetch api.

ok gilles@


# 1.604 26-Dec-2018 eric

move the table backend name in the backend struct.
remove unused function.

ok gilles@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.603 23-Dec-2018 eric

remove dead code

ok gilles@


# 1.602 23-Dec-2018 eric

Simplify the table backend interface: lookup results are returned
as strings, and parsing is handled by the upper layer.

ok gilles@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.601 22-Dec-2018 gilles

introduce 'rcpt-to' builtin filter, can only be used on 'rcpt-to' hook


# 1.600 22-Dec-2018 gilles

introduce 'mail-from' builtin filter, can be applied on the 'mail-from',
'rcpt-to', 'data' and 'commit' phases.


# 1.599 22-Dec-2018 gilles

introduce 'helo' builtin filter, can be used on any hook but 'connect'


# 1.598 22-Dec-2018 gilles

introduce new matching criteria 'from rdns' to match sessions based on rDNS
of the client, works with literal and tables, both string and regex:

match from rdns "mx1.poolp.org" for any action blahblah


# 1.597 21-Dec-2018 gilles

since we already support regex lookups in tables for builtin filters, let's
also support regex lookups in match rule criterias performing table lookups

ok millert@


# 1.596 21-Dec-2018 gilles

implement some additional builtin filters:
check-src-{table,regex}, check-rdns-{table,regex}

make sure that these builtins may be used at all phases


# 1.595 21-Dec-2018 gilles

bring in new grammar for filters, allowing filter chains and plugging of
different filters & chains on different interfaces.

in this diff, proc filters are still disabled as they're missing on very
important piece of logic.

ok eric@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.594 13-Dec-2018 gilles

in event reports, use a struct timeval instead of time_t since we want more
than second precision

discussed with eric@


# 1.593 12-Dec-2018 gilles

remove unused prototypes


# 1.592 12-Dec-2018 gilles

add tx-data reporting event


# 1.591 11-Dec-2018 gilles

do some imsg renaming to make them more clear


# 1.590 11-Dec-2018 gilles

remove unused imsg names


# 1.589 11-Dec-2018 gilles

factor smtp-in and smtp-out reporting code


# 1.588 11-Dec-2018 gilles

report filter responses to smtp


# 1.587 11-Dec-2018 gilles

generate an event when a helo name identifies a link


# 1.586 11-Dec-2018 eric

Improve the cert_*() interface. Use the return value to tell whether
the request is pending (waiting for an async event) or not. Success
or failure is always reported through the callback function.

ok gilles@


# 1.585 09-Dec-2018 gilles

add check-fcrdns builtin filter

ok eric@


# 1.584 09-Dec-2018 gilles

no longer pass rdns in all filtering requests, they can be retrieved from
the filter session.


# 1.583 09-Dec-2018 gilles

add client and listener address, as well as client rDNS and FCrDNS lookup
result to the filter_session structure upon filter session allocation. it
will allow me to simplify all filter hooks.


# 1.582 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


# 1.581 07-Dec-2018 eric

Refactor certificate initialization and verification.
Factorize code duplicated in smtp_session.c and mta_session.c
Implement a simple callback interface, with proper request management
and simplified imsg protocol.

Only add the necessary parts for now.
Exisiting code path will be adapted later.

input from gilles@ sunil@
ok gilles@


# 1.580 06-Dec-2018 gilles

link-connect event report had an empty fcrdns field, but now that eric@ has
plugged fcrdns in the smtp_session we can fill the field with a value


# 1.579 06-Dec-2018 gilles

introduce tx-mail and tx-rcpt report events


# 1.578 06-Dec-2018 gilles

allow passing data lines to proc filters

ok eric@


# 1.577 06-Dec-2018 gilles

in mda variables expansions, do not consider empty strings as errors since
an empty %{sender} is really a mailer-daemon and not an error

reported and initial diff by Lauri Tirkkonen <lotheac@iki.fi>
commit is a revised version of the diff based on a discussion with eric@


# 1.576 06-Dec-2018 gilles

bring the first bits of DATA filtering plumbing but bypass it for now

ok eric@


# 1.575 30-Nov-2018 gilles

prepare for smtp-out reporting and while at it, make a few changes to the
report format


# 1.574 29-Nov-2018 gilles

introduce FILTER_COMMIT which will allow taking a decision at DATA commit
time, unusable yet but necessary for the upcoming serie of diffs.

ok eric@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.573 08-Nov-2018 gilles

when reporting tx events, report tx id
when reporting tx commit, report data size
report tx-envelope events


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.572 03-Nov-2018 gilles

only apply filter rules to filtered interfaces


# 1.571 03-Nov-2018 gilles

check-rdns builtin filter, to be improved


# 1.570 03-Nov-2018 gilles

bring plumbing for proc filters

ok millert@, eric@, jung@


# 1.569 03-Nov-2018 gilles

bring plumbing for builtin filters

ok millert@, eric@, jung@


# 1.568 02-Nov-2018 gilles

report rDNS in link connect event


# 1.567 02-Nov-2018 gilles

pass struct sockaddr_storage instead of ss_to_text() in reporting


# 1.566 01-Nov-2018 gilles

teach smtp process how to report smtp events to lka and teach lka how to
report these events to a proc

ok millert@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.565 01-Nov-2018 gilles

introduce K_REGEX table type and table_regex_match(), unused for now

ok eric@


# 1.564 01-Nov-2018 gilles

allow smtpd to fork processes at startup and maintain a socketpair with
them.

ok jung@, eric@


# 1.563 31-Oct-2018 gilles

add helper valid_smtp_response() to be used in upcoming commits


Revision tags: OPENBSD_6_4_BASE
# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.562 24-Sep-2018 eric

Allow to use the "tls" keyword on any relay action to force TLS, with
strict certificate validation. The "no-verify" becomes optional.

ok gilles@ millert@ semarie@


# 1.561 19-Sep-2018 eric

rename the ill-named "flags" member to "as_host" in domain structure.
remove yet another useless relay flag while there.

ok gilles@


# 1.560 17-Sep-2018 eric

simplify code path for backup relay and remove useless flag

ok gilles@


# 1.559 08-Sep-2018 eric

use symbolic integer values for the different tls options when relaying,
rather than a confusing set of flags.

ok gilles@


# 1.558 04-Sep-2018 gilles

upon mda failure, smtpd would assume tempfail and retry. this is at odds
with the other MTA which assume a permfail unless the exit status is one
of a specific set. make smtpd honour the same exit statuses as postfix.

note that all errors that occur before the user mda is executed (fork, pipe
and related) are still considered tempfail, only errors coming from the mda
itself are handled as permfail.

this commit is a temporary solution as i believe the SIGCHLD handler is way
more complex than it should be and we'll simplify it after 6.4 is out.

ok eric@


# 1.557 31-Aug-2018 eric

switch to improved incoming message parser:
- simpler interface not using callbacks
- no hard-coded line length
- avoid unnecessary string copy

ok gilles@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.556 25-Jul-2018 eric

Implement a generic interface to forward resolver queries to the lka
process. Use it for the reverse lookups required by smtp and mta.

Until now, DNS-related lookups were implemented using ad-hoc IMSGs
between the lka and other processes. It turns out to be confusing and
difficult to maintain/extend. So we want to replace this with a better
set of IMSGs matching the standard resolver interface.

ok gilles@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.555 18-Jun-2018 gilles

simplify parse_config() further so it no longer has any side effect outside
of parse.y, there's still work to be done but it's now able to run twice if
we want (we don't) without failing due to some global side-effect.

ok millert@


# 1.554 18-Jun-2018 gilles

split smtp_accept() in two parts: the accept part, the session init part,
while at it allow smtp_session() to receive a pre-allocated struct io

ok millert@
diff contributed by Antoine Kaufmann


# 1.553 16-Jun-2018 gilles

rework the table API so that it takes a struct smtpd * context in parameter
of functions creating, looking up or destroying tables.

this is a first step in cleaning up parse.y so it doesn't have side effects
outside of parse_config(), bringing nothing but making code cleaner.

ok millert@


# 1.552 07-Jun-2018 eric

remove unused flags and obsolete comments

ok gilles@


# 1.551 06-Jun-2018 eric

remove fields that are found in struct dispatcher from struct relayhost

ok gilles@


# 1.550 05-Jun-2018 eric

remove struct relayhost from struct envelope.

ok gilles@


# 1.549 04-Jun-2018 gilles

add support for mda wrappers allowing postmaster to define command wrappers
that will be executed (with recipient privileges) before calling the users'
mail delivery agent

ok eric@


# 1.548 03-Jun-2018 gilles

split forkmda() in two:
- forkmda() creates the process that will be used for the delivery and does
the switching of privileges then calls mda_unpriv()
- mda_unpriv() runs with privileges of the recipient, it expands variables,
sets up environment and executes the mda

ok millert@ and eric@


# 1.547 01-Jun-2018 eric

Require a valid certificate by default when relaying through a smarthost.
Add "tls no-verify" relay option to disable it.

suggested and initial diff by semarie@.

ok gilles@


# 1.546 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.545 29-May-2018 eric

remove unused function

ok gilles@


# 1.544 29-May-2018 eric

no need to parse and dump the relayhost in the lookup process.

ok gilles@


# 1.543 29-May-2018 gilles

provide mail user agents with the same environments as Postfix

ok millert@, eric@


# 1.542 24-May-2018 gilles

bump version, this will be a big release when OpenBSD 6.4 is released :-)


# 1.541 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


# 1.540 14-May-2018 gilles

kill corrupt / uncorrupt queue mechanism as it has never been usable and it
will be made irrelevant when the new config comes up soon

ok eric@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.539 26-Apr-2018 eric

sync log.h with other daemons

ok gilles@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


Revision tags: OPENBSD_6_3_BASE
# 1.538 14-Mar-2018 gilles

bump minor version just to be sure it makes release :-)

ok gilles@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@


# 1.537 02-Jan-2018 gilles

we haven't updated the version in a while despite many commits which is
confusing for people running the portable version


Revision tags: OPENBSD_6_2_BASE
# 1.536 08-Sep-2017 eric

remove more filter-related cruft

ok gilles@


# 1.535 13-Aug-2017 eric

bypass the filter code for incoming smtp sessions.
experimental support for filters has been removed from the config
parser already, and we want to get rid of the remaining code.

ok gilles@


# 1.534 04-Aug-2017 gilles

the PURGE_EVERYTHING flag used to purge config bits was inaccurate

ok eric@


# 1.533 27-Jul-2017 sunil

smtpctl(8): Use an int to determine mode instead of __progname.

Ok millert@ gilles@


# 1.532 26-May-2017 gilles

move variables expansion out of lka_session into their own file, this is a
mechanical diff to simplify a bit the lka code and prepare for moving
variables outside of the lookup process into the chrooted mda process.
no functional change for now.

ok eric@


# 1.531 22-May-2017 gilles

- filters are currently broken, do not allow using them until we're done


Revision tags: OPENBSD_6_1_BASE
# 1.530 13-Feb-2017 gilles

allow negation of authenticated keyword:
accept ! authenticated [...]

ok sunil@, jung@


# 1.529 03-Feb-2017 guenther

Stop assuming that in_{addr,port}_t are typedefed in <sys/types.h> and
instead pull in <netinet/in.h> or <arpa/inet.h> when those are needed.

ok florian@ beck@ millert@


# 1.528 09-Jan-2017 reyk

smtpd joins the 7 other daemons that share the same log.c file.

The only major difference was the "log_trace" concept that is only
used by smtpd - move it from log.c into util.c and make it a local
concept. This also needed to rename the global "verbose" variable to
"tracing" in a few places.

OK krw@ gilles@ eric@


# 1.527 30-Nov-2016 eric

remove unused iobuf helpers


# 1.526 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.525 25-Nov-2016 gilles

assign an id to each rule in the ruleset, first step towards an MTA layer
and scheduler simplification

ok eric@


# 1.524 17-Nov-2016 eric

Add io api functions for dealing with buffered data, as wrapper around
their iobuf counterparts.

ok gilles@ sunil@


# 1.523 04-Sep-2016 eric

Remove the "smtpctl stop" command.
The daemon is stopped with kill(1).

ok gilles@


# 1.522 03-Sep-2016 eric

get rid of the type-checking system on internal messages.
bump all imsg protocol versions since message format changed.

ok gilles@ sunil@


# 1.521 01-Sep-2016 eric

remove noop function

ok sunil@


# 1.520 01-Sep-2016 eric

get rid of the imsg buffer usage profiling code.

ok gilles@ jung@ sunil@


# 1.519 31-Aug-2016 eric

Remove dead code. queue_flow_control() has never been used and is
probably a bad idea.

ok gilles@


# 1.518 31-Aug-2016 gilles

introduce "authenticated" parameter so rules may apply to authenticated
sessions specifically

ok eric@, sunil@, jung@


# 1.517 31-Aug-2016 gilles

allow overriding the subaddressing delimiter with subaddressing-delimiter
keyword, the default is still +

ok eric@, sunil@


Revision tags: OPENBSD_6_0_BASE
# 1.516 24-Jul-2016 gilles

bump version

ok deraadt@


# 1.515 28-May-2016 eric

Implement the fork+exec pattern in smtpd.

The parent process forks child processes and re-exec each of them with
an additional "-x <proc>" argument. During the early setup phase, the
parent process sends ipc socket pairs to interconnect the child
processes as needed, and it passes the queue encryption key to the
queue if necessary. When this is done, all processes have their
environment set as in the fork-only case, and they can start doing
their work as before.

ok gilles@ jung@


# 1.514 25-Mar-2016 krw

Nuke session_socket_blockmode() and session_socket_linger(). Use
the identical io_set_blocking() and io_set_linger().

Since both are always called to turn off blocking or lingering,
nuke the parameter and associated enum in favour of "just doing the
right thing".

While passing remove the unneeded last parameter to the remaining
fcntl(F_GETFL).

Finally, rename the functions to io_set_nonblocking() and
io_set_nolinger() for clarity.

No functional change.

Started with a sweep of fcntl() usage inspired by guenther@.

ok gilles@


Revision tags: OPENBSD_5_9_BASE
# 1.513 21-Feb-2016 gilles

bump version


# 1.512 13-Feb-2016 gilles

handle enqueuer socket as a regular listener that can be configured with
"listen on socket". this simplifies a bit of code, removes some special
cases and will allow attaching filters & masking source just as on lo0.

diff from Peter Bisroev <peter@int19h.net>
ok gilles@, jung@


# 1.511 05-Feb-2016 jung

remove no longer relevant ifndef

suggested by gilles


# 1.510 27-Jan-2016 sunil

Check imsg data length before use.

Ok jung@ gilles@ eric@


# 1.509 04-Jan-2016 jung

switch to /usr/local/libexec when looking for -extras and drop loop iterating
paths

this effectively reverts table.c r1.21 which was mainly introduced for a smooth
transition in -current

ok gilles


# 1.508 13-Dec-2015 gilles

smtpd is no longer 5.4.6


# 1.507 13-Dec-2015 gilles

refactor a bit to move the SNI handling away from smtp_session into smtp

ok sunil@, jung@


# 1.506 12-Dec-2015 gilles

allow overriding the default cipher-suite

ok jung@, sunil@, millert@


# 1.505 12-Dec-2015 gilles

add bits so local enqueuer can run filters when they are enabled


# 1.504 12-Dec-2015 gilles

expose foreground_log in smtpd.h so filters can inherit it


# 1.503 12-Dec-2015 gilles

sender and recipient are mail addresses, not pathnames, use proper define


# 1.502 12-Dec-2015 gilles

use smtpd specific define for table name sizes


# 1.501 12-Dec-2015 gilles

pki name and ca name must match a hostname, use HOST_NAME_MAX


# 1.500 12-Dec-2015 gilles

do not limit usernames to LOGIN_NAME_MAX in places where "virtual users"
may be used, in such places an email address may be specified.


# 1.499 12-Dec-2015 gilles

rename an smtpd specific define


# 1.498 12-Dec-2015 gilles

prepare some imsg structures for upcoming diff to support wildcard ca


# 1.497 11-Dec-2015 gilles

rename field member + whitespaces


# 1.496 11-Dec-2015 gilles

add filter.c prototypes, unused for now


# 1.495 11-Dec-2015 gilles

prepare smtpd.h for masquerading


# 1.494 07-Dec-2015 sunil

Merge makemap(8) into smtpctl(8).

Ok gilles@, jung@


# 1.493 03-Dec-2015 jung

introduce limit session keyword replacing fixed values

original diff from Renaud Allard

ok gilles


# 1.492 01-Dec-2015 gilles

add received-auth parameter to listener to identify authenticated sessions
in locally appended Received header when enabled

ok millert@, jung@


# 1.491 01-Dec-2015 gilles

add IMSG_SMTP_CHECK_SENDER in preparation for another diff


# 1.490 01-Dec-2015 gilles

prepare the ground for the CA certificate handling refactor, this commit
adds the parse.y bit + structures & members needed but does not make use
of it yet


# 1.489 30-Nov-2015 gilles

add ca_name field to some structures in preparation for a larger
diff to refactor handling of CA certificates


# 1.488 30-Nov-2015 gilles

when looking up tables, start in /usr/local/libexec before /usr/libexec, so
ports/packages can be installed in the proper place

ok jung@


# 1.487 30-Nov-2015 gilles

mechanical rename of some IMSG constants

ok sunil@, ok jung@


# 1.486 30-Nov-2015 sunil

While delivering to lmtp or mda, accept optional "as user" parameter
whose privileges would be used instead of the default.

Ok gilles@ jung@


# 1.485 23-Nov-2015 gilles

allow table API to lookup for mailaddr mappings

ok sunil@, ok jung@


# 1.484 05-Nov-2015 sunil

Implement smtpctl uncorrupt <msgid>

"uncorrupt" moves envelopes from corrupt bucket back to the queue
for further discovery by the daemon.

After correcting the corrupt envelopes, admin could now...

# smtpctl uncorrupt msgid
# smtpctl discover msgid

to schedule the messages.

Ok gilles@


# 1.483 29-Oct-2015 sunil

Implement smtpctl discover <evpid|msgid>.

discover subcommand schedules envelopes manually moved to the queue.
It triggers a queue walk searching for envelopes with the given id,
schedules them and informs the user number of envelopes scheduled.
Admins no longer would need to restart the daemon to discover
manually moved messages.

Ok gilles@


# 1.482 28-Oct-2015 gilles

masquerade and senders map require being able to lookup mailaddr structures
in tables, prepare for such features by bringing the helpers + smtpd.h part

ok millert@


# 1.481 28-Oct-2015 gilles

aliases support resolving to maildir:/path

ok sunil@ millert@


# 1.480 27-Oct-2015 gilles

aliases_virtual_check() has been unneeded for a while

ok jung@, ok sunil@, ok millert@


# 1.479 21-Oct-2015 jsing

Only enable SSL_VERIFY_PEER when the verify option is set on a listener.

Always enabling SSL_VERIFY_PEER unnecessarily increases the number of
messages/bytes in the TLS handshake and increases our attack surface,
since we request and then process client certificates.

ok gilles@


# 1.478 17-Oct-2015 gilles

mailaddr_match() allows comparing two struct mailaddr taking into account
catchall and +-tags

ok millert@ and jung@ for util.c


# 1.477 14-Oct-2015 gilles

smtpd in tree is no longer neither 5.4.4, nor 5.4.5, bump SMTPD_VERSION


# 1.476 09-Oct-2015 gilles

turn our local enqueuer setgid _smtpq and restrict access to offline queue,
the enqueuer will revoke group and regain real gid right after mkstemp.

this would have prevented the symlink/hardlink attacks against offline, and
it will avoid having to deal with new ways users can mess with it.

ok eric@, ok millert@


# 1.475 07-Sep-2015 gilles

when bypassing the enqueuer, insert Message-Id header if none was found and
the client has connected from a loopback interface.

ok millert@ eric@


Revision tags: OPENBSD_5_8_BASE
# 1.474 19-Apr-2015 gilles

Incorrect logic in smtpd(8) can lead to unexpected client disconnect, invalid
certificate in SNI negotiation or server crash.

spotted by Edwin Torok


Revision tags: OPENBSD_5_7_BASE
# 1.473 20-Jan-2015 deraadt

branches: 1.473.2;
use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


# 1.472 24-Dec-2014 eric

bump version


# 1.471 14-Dec-2014 gilles

these are no longer used, remove


# 1.470 16-Nov-2014 bluhm

Convert the logic in yyerror(). Instead of creating a temporary
format string, create a temporary message.
OK doug@


# 1.469 15-Oct-2014 gilles

when From, To and Cc headers present users without domains, append the
listener hostname to avoid smtpd relaying a header that will be rewritten
by the destination MX.

ok eric@


Revision tags: OPENBSD_5_6_BASE
# 1.468 10-Jul-2014 eric

branches: 1.468.4;
Improve the scheduler, better and simpler.

- Get rid of the scheduler_batch structure. The scheduler can now return
envelopes of different types in a single run, interlacing them to avoid
batch effects.

- Ask for an acknowledgement from the queue when removing or expiring
an envelope to benefit from the inflight envelope limitation mechanism.
This ensures that the scheduler always keeps sending envelopes at a rate
that the queue can sustain in all cases.

- Limit the number of envelopes in a holdq. When a holdq is full,
new envelopes are put back in the pending queue instead, with a
shorter retry time.

- Plumbing for proc-ified schedulers.

imsg version bump. smtpctl stop before updating.

ok gilles@


# 1.467 09-Jul-2014 eric

add a "no-dsn" listener option to disable DSN extension.


# 1.466 09-Jul-2014 eric

config parser improvements:

- fail if the same option is specified multiple times on a listener
- prompt for queue encryption key after config parsing, not during.
- add ip addresses to localnames table
- prepare for filters


# 1.465 08-Jul-2014 eric

update filter configuration parsing (not plugged yet)


# 1.464 08-Jul-2014 eric

get rid of mfa leftovers


# 1.463 08-Jul-2014 eric

various queue improvements:

- add a "close" hook to the backend API.
- improve the sync() pattern in queue_fs: only sync at commit
time and not for every envelope creation
- various fixes to the experimental external queue API.


# 1.462 08-Jul-2014 eric

Update the table API: lookup functions can take an optional parameters
dictionnary (currently not set). While there, add a helper for forking
external backends, and remove unused table functions.

ok gilles@


# 1.461 04-May-2014 reyk

Create a new default RSA engine instead of patching the existing one
if none is available. Fixes SSL/TLS and a possible fatalx() on
machines without a default RSA engine.

Thanks to Bjorn Ketelaars for reporting and testing.

ok gilles@ (for the relayd part)


# 1.460 01-May-2014 reyk

Move RSA keys from "lka" to a new dedicated "ca" process because lka
is handling some async requests and shouldn't be busy with sync RSA.

ok gilles@


# 1.459 30-Apr-2014 gilles

when using maildir, do not create automatically create folders to match tag
in email address (ie: gilles+tag => ~/Maildir/.tag), instead use the folder
if it already exists and deliver to the mail Maildir otherwise.

ok eric@ and chl@


# 1.458 30-Apr-2014 reyk

The RSA engine (used by pony) has to wait for a response from the
privileged process (lka) and receive the imsgs in a while loop
synchronously. But the lka also sends other imsgs (DNS etc.) that can
still be queued up in the buffer when waiting for the RSA response.
This only happens under load with many concurrent connections. For
now, we just call the pony imsg handler for non-RSA imsgs that are
already in the buffer.

ok gilles@ eric@ blambert@


# 1.457 29-Apr-2014 reyk

Implement RSA privilege separation for OpenSMTPD, based on my previous
implementation for relayd(8). The smtpd(8) pony processes (mta
client, smtp server) don't keep the private keys in memory but send
their private key operations as imsgs to the "lookup"/mta process.
It's worth mentioning that this prevents acidental private key leakage
as it could have been caused by "Heartbleed".

ok gilles@


# 1.456 29-Apr-2014 reyk

Remove unused arguments from ssl_smtp_init()

ok gilles@


# 1.455 19-Apr-2014 gilles

certs are looked up by hostname, the size of the buffer should use the
max hostname len, not max pathname len as before


# 1.454 09-Apr-2014 eric

Zap the mfa process. It is not currently doing anything, and content filtering
will be done at session level anyway.

ok gilles@


# 1.453 09-Apr-2014 eric

remove useless define for banner

ok gilles@


# 1.452 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


# 1.451 22-Mar-2014 gilles

disable the imsg buffers profiling code unless requested, this will prevent
all processes from waking up every second


Revision tags: OPENBSD_5_5_BASE
# 1.450 17-Feb-2014 eric

branches: 1.450.2;
new "smtpctl show status" command to show if mta/mda/smtp are currently running or paused.


# 1.449 10-Feb-2014 eric

tweak usage() and bump version.


# 1.448 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.447 04-Feb-2014 eric

Allow the admin to pause relaying to a specific domain:
- smtpctl pause mta from <source> for <domain>
- smtpctl resume mta from <source> for <domain>
- smtpctl show mta paused


# 1.446 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.445 04-Feb-2014 eric

pki code cleanup

- rename "struct ssl" and "cert" to "struct pki" and "cert" to "pki_name"
- inherit pki conf on fork instead of passing it through imsg at startup
- implement SNI on smtp listeners


# 1.444 04-Feb-2014 eric

extend allowed charset for email address, escape all potentially dangerous ones.


# 1.443 04-Feb-2014 eric

add base64_encode/base64_decode helpers


# 1.442 04-Feb-2014 eric

get rid of fdlimit()


# 1.441 06-Dec-2013 eric

now at 5.4.1


# 1.440 05-Dec-2013 eric

move defines around


# 1.439 03-Dec-2013 eric

Rework the envelope flushing loops in mta to avoid sending all delivery
notifications in one go to the queue. Simplify code in the process.


# 1.438 30-Nov-2013 eric

do not hardcode scheduler batch size, and reduce default limit to avoid
hammering effects.


# 1.437 28-Nov-2013 eric

limit the number of envelopes to recall in the hoststat cache.


# 1.436 20-Nov-2013 eric

Rework the mda and scheduler to use the holdq mechanism instead of
tempfail for limiting the number of pending deliveries to the same
user. This allows to reach optimal delivery time even in case of
burst, while keeping the number of inflight envelopes low.


# 1.435 19-Nov-2013 eric

Add a limit on the number of inflight envelopes. The scheduler suspends
scheduling of mta/mda envelopes until the number of inflight envelopes
falls below that line.


# 1.434 18-Nov-2013 eric

Allow overriding the local ca


# 1.433 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.432 30-Oct-2013 eric

add "smtpctl show relays" and "smtpctl show hosts" commands


# 1.431 29-Oct-2013 eric

add missing heloname field for relayhost.
differenciate relays with different helotable/heloname.
improve code a bit.


# 1.430 29-Oct-2013 eric

use "/etc/mail/mailname" instead of "/etc/mailname" and make it a define.


# 1.429 29-Oct-2013 eric

Report mta sessions errors on the route rather than on the MX.
If a route has too many of these errors, disable it for a while.
Reset the error counter for a route when it is re-enabled or when
it could establish a connection successfully.


# 1.428 27-Oct-2013 eric

Implement a feedback mechanism which allows the mta to "hold" envelopes
in the scheduler when it has too many tasks for a given relay. The
envelopes are put on a wait queue, and are not scheduled again until
the mta "releases" some envelopes from that queue.

It prevents from having too many inflight envelopes, which are out of reach
for the admin.


# 1.427 27-Oct-2013 eric

Make the filter infrastructure move forward.
This is a work-in-progress and it's not supposed to be useable for now.


# 1.426 27-Oct-2013 eric

Create the control socket in the parent process to abort early if
another smtpd instance is running. Close the inherited socket in
every forked process but control.


# 1.425 26-Oct-2013 eric

Simplify code for loading and dumping envelopes. Makes it much easier
to deal with automatic upgrade between envelope versions at load time.


# 1.424 25-Oct-2013 eric

local enqueuer improvements:

- parse the whole input before trying to establish the connection
to the local socket: fixes timeout problems when reading the output
of a long running program.

- use sendmail(8)-like exit status.


Revision tags: OPENBSD_5_4_BASE
# 1.423 19-Jul-2013 eric

We are basically at 5.4 now


# 1.422 19-Jul-2013 eric

Implement a scheduler_proc backend


# 1.421 19-Jul-2013 eric

Many MTA improvements:

- Better transient error handling logic: failing destinations are
automatically disabled for a while. When a destination is active
again, ask the scheduler to retry previous envelopes immediatly.
- More informative error report when all routes fail for a mail.
- Implement a "smtpctl show hoststats" command to get the latest stat
message per MX domain.
- Implement a "smtpctl show routes" command to show the state the
currently known routes to remote MXs.
- Implement a "smtpctl resume route" command to re-enable a route that
has been disabled.
- Do not hardcode limits
- Minor code improvements


# 1.420 19-Jul-2013 eric

Assorted queue improvements:
- cleanup the internal queue backend API and get rid of the QOP_* thing.
- implement a queue_proc backend
- rename queue_fsqueue.c to queue_fs
- enable support for queue encryption
- add an envelope cache
- better logging and error reporting


# 1.419 19-Jul-2013 eric

Add a table_proc backend for delegating table lookups to another
process. Stop building experimental table_sqlite and table_ldap as
they will be provided as external backends.


# 1.418 19-Jul-2013 eric

Move the filter infrastructure forward.


# 1.417 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.416 19-Jul-2013 eric

New implementation for smtpctl and the command line parser. Allows
richer syntax, and makes the code way simpler to follow and extend
with new commands.


# 1.415 19-Jul-2013 eric

Get rid of env->sc_pw and env->sc_pwqueue. Early queue initialization
now happens in queue_init(), and backends take the queue passwd as
parameter in their init function.

Remove useless SMTPD_FILTER_USER while there.


# 1.414 19-Jul-2013 eric

Introduce expand string modifiers


# 1.413 19-Jul-2013 eric

Remove useless sc_pid from struct smtpd.


# 1.412 19-Jul-2013 eric

get rid of sa_set_port() and its awfully contorted implementation


# 1.411 04-Jun-2013 eric

we are at 5.3.3 now.


# 1.410 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.409 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


# 1.408 06-Mar-2013 sthen

as done in ospf{,6}d/relayd, sync yyerror in various other daemons with
that from bgpd, so that it logs to syslog when daemonized.


Revision tags: OPENBSD_5_3_BASE
# 1.407 15-Feb-2013 eric

add missing bits for lmtp support (from Ashish SHUKLA).

ok gilles@


# 1.406 14-Feb-2013 gilles

- log smtpd version at startup

ok eric@


# 1.405 14-Feb-2013 gilles

- smtpctl trace expand, enables tracing of aliases expansion
- replace "users" keyword with "userbase" when providing alternate userbase
- disambiguise expansion nodes when expanding across domains and userbases
- allow use of '=' instead of '=>' when declaring a mapping

ok eric@


# 1.404 10-Feb-2013 eric

When getting the next batch of envelope to schedule, use an array to
store envelope ids, rather than a dynamic list.

ok gilles@


# 1.403 05-Feb-2013 gilles

unbreak broken smtpctl table update

fix by eric and I, ok eric@


# 1.402 31-Jan-2013 eric

assorted fixes spotted by Coverity.
some log message updates.

ok gilles@


# 1.401 31-Jan-2013 eric

do not need to tweak the socket sndbuf, now that the envelopes are passed
in compressed form. reduce the default size for envelope messages.

ok gilles@


# 1.400 28-Jan-2013 eric

use a stripped-down mta_envelope structure in the mta process.
reduces memory footprint by a great deal when relaying lots of messages.

ok gilles@


# 1.399 28-Jan-2013 gilles

- introduce 'smtpctl trace lookup' to trace lookup process
- improve logging of the transfer process

trace by me, logging by eric


# 1.398 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.397 23-Nov-2012 eric

Replace the qwalk API (to retreive on disk envelopes at runtime) with
a simple QOP_WALK queue operation. Some knf and formating fixes while
there.

ok gilles@


# 1.396 20-Nov-2012 eric

Allow "smtpctl show queue" to run in "online" mode if the smtpd server
is running. The scheduler sends the runtime state of each envelope to
the queue process which loads the envelope, fills the runtime bits and
sends the envelope back to the client. Iteration over the envelope set
happens in small chunks to make the request interruptible and to allow
the server to keep doing its job in the meantime.

Adpat "smtpctl schedule-all" to schedule the messages one by one using
the same iteration mechanism.

Document "smtpctl monitor" and "smtpctl show queue".

ok gilles@


# 1.395 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.394 02-Nov-2012 eric

Add a "kick counter" that gets incremented on each command, to detect
clients that don't do their best to do something useful, and just hog
the session. When that kick counter reaches the limit, the client is
disconnected. The counter is reset after the first HELO/EHLO command,
after tls is established, after a succesful authentication, and after
a message is accepted. It is decremented when a RCPT is accepted.

ok gilles@


# 1.393 02-Nov-2012 eric

Consistency and robustness improvements in mda:

- Introduce a mda_getlastline function(); improve the code to avoid
useless allocations and string formatting; make it return the last
line with content (skip trailing empty lines if found).
- Add a mechanism by which the mda can request the parent to abort a
local delivery by killing the process.
- Use ioev/iobuf for draining data to the delivery process.
- Make sure to catch all transient errors and make them result in a
tempfail rather than calling fatal().
- Make sure that the envelope status is properly set for all failures.
- Stop using SMTP response codes; it makes no sense in this context.

ok gilles@


# 1.392 02-Nov-2012 eric

Make counters more informative in the scheduler:

- Change the scheduler backend API a bit: commit() and rollback()
API calls return the number of envelopes added or canceled; put
the number of envelopes in the structure returned by batch().

- Properly report the number of incoming, registered, removed and
expired envelopes, as well as the outcome of deliveries.

ok gilles@


# 1.391 28-Oct-2012 eric

Limit the number of messages that can be enqueued on a single SMTP
connection, and the number of recipients in each of them.

ok gilles@ chl@


# 1.390 16-Oct-2012 eric

MAX_RULEBUFFER_LEN is too small, bump it.

discussed with gilles@


# 1.389 14-Oct-2012 gilles

introduce map_file.c which will deprecate map_stdio.c

The idea is to have a file-backed map but to have smtpd(8) cache the maps
so that it cannot be partially read if edited while mail is received. The
file is read and converted to a static map (map_static.c), changes aren't
visible to smtpd until an explicit: smtpctl update map which reads file,
builds a new static map and invalidates the former.

partial-read issue discussed with beck@ and halex@
idea to convert internally to a static map by eric@

diff ok eric@ and chl@


# 1.388 12-Oct-2012 eric

Extend the "retry" field to 16 bits. The new quadratic retry formula
makes the maximum retry delay a bit to small on 8 bits.

ok gilles@ chl@


# 1.387 11-Oct-2012 gilles

- map_create() takes a map_src not a map_kind

ok eric@ and chl@


# 1.386 11-Oct-2012 gilles

- replace "from all" and "for all" with "from any" and "for any"

ok eric@, chl@


# 1.385 10-Oct-2012 gilles

F_BACKUP and ROUTE_BACKUP must be sync-ed for now, otherwise smtpd won't
work as a backup MX ...

bug experienced by todd, verified and analyzed by eric


# 1.384 10-Oct-2012 gilles

teach smtpctl how to display envelopes and messages using their id.
this allows an admin to inspect the queue without having to manually
extract bucket and find the path to an envelope or message.

diff by Sunil Nimmagadda <sunil@poolp.org>

ok eric@, chl@ and I


# 1.383 10-Oct-2012 eric

For each alias node, mark if it has been expanded from an alias map or
from a .forward file. Local deliveries for files and filters expanded
from an alias map are run as user _smtpd.

issue reported by tood@

ok gilles@ todd@


# 1.382 09-Oct-2012 gilles

- allow a listen statement to impose tls on its clients;
- make listen statements impose authentication if 'auth' is specified and
to make it optional if 'auth-optional' is specified;
- sync documentation accordingly

with ideas and input from beck@ and halex@, ok eric@


# 1.381 08-Oct-2012 gilles

disk space is cheap but we still want to limit the default size of a body
to a sane default for everyone.


# 1.380 07-Oct-2012 eric

Implement a simple wait queue API. The idea is to allow multiple "waiters"
to wait on the same "tag" for a deferred result.

A waiter is a callback and a void *argument. The first waiter (the one for
which waitq_wait() returns true) is supposed to run some code that leads to
waitq_run() being run, which will destroy that waitq and call all callbacks
in turn.

Not used at the moment, but will be soon.

ok gilles@ chl@


# 1.379 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.378 03-Oct-2012 gilles

we reintroduced a bug that was fixed 2 years ago with the aliases rewrite:

During the entire expansion process, a username may be larger than
MAXLOGNAME because it may be an alias going through another expansion.
We should use a buffer that's large enough to fit a mailaddr user-part so
we avoid hitting a truncation check leading to a fatal().

ok eric@, ok chl@


# 1.377 03-Oct-2012 gilles

disallow root deliveries for "deliver to filename" and "deliver to mda"
rules, we only allow them for mbox and maildir though users should really
create a root alias ...

discussed with eric@ and chl@, ok both


# 1.376 30-Sep-2012 gilles

- add decision to the rule so that we can actually perform a reject match
ie:

reject from 192.168.1.0/24 for domain "openbsd.org"
accept from 192.168.0.0/16 for domain "openbsd.org" deliver to mbox

it was documented but not working.

ok eric@ & chl@


# 1.375 29-Sep-2012 eric

some mfa_session cleanups.

- move mfa_session() prototype to smtpd.h
- make mfa session use a tree
- make static functions static
- merge mfa_session_init() into mfa_session()

ok chl@


# 1.374 29-Sep-2012 eric

finally remove rule member from struct envelope.

"wow!" gilles@


# 1.373 29-Sep-2012 eric

Remove support for "as user" for local deliveries.
It's not documented and not implemented.

ok gilles@


# 1.372 28-Sep-2012 eric

some smtpd.{c,h} cleanups:

- move struct child to smtpd.c
- make it use a tree keyed on the pid
- change child_add to take the title directly as a const char *
- remove useless child_lookup() and child_del()
- remove CHILD_INVALID

ok chl@ gilles@


# 1.371 28-Sep-2012 eric

Move mda_session to mda.c, and make it use a tree instead of a list,
but still use uint32_t keys since ithe key is used as peerid in msg.

ok gilles@


# 1.370 28-Sep-2012 eric

smtpd.h/control.c cleanups:

- move session_socket_* prototypes under util.c
- move struct ctl_conn in control.c
- make static functions static
- remove unused functions
- call unlink() in control_shutdown()
- make control_close() take a ctl_conn * instead of a fd

ok chl@ gilles@


# 1.369 27-Sep-2012 eric

clarify the alias expansion code.

The session manages a list of nodes to process. A node has a link to the
parent node from which it has been expanded, and a link to the rule that
led to its creation. Depending on its type and the associated rule, each
node is either "expanded" to create new nodes or "submitted" to create a
final envelope. Nodes which have already been seen, either processed or
not, are discarded to avoid loops.

The expansion process is bootstrapped by creating an EXPAND_ADDRESS node
from the original dest, with no rule and no parent. It is done when all
nodes have been expanded or if an error occurs before. The expand depth
is limited 5 levels. The whole expansion fails if the limit is reached.

While there, make sure that only one .forward file is queried at a time,
and only append the subfolder tag in the maildir case.

Fixe issues with some virtual map setups where the dest would get mixed
up, and make the whole expansion process generally easier to follow.

ok chl@ gilles@


# 1.368 26-Sep-2012 eric

Stop using the delivery_data union (field "to") in delivery_mda.
It's confusing and not necessary as it's only used for "buffer".
Instead, just add a "buffer" member in the structure and rename
"as_user" to "user".

The delivery_data union becomes an anonymous union in expandnode,
which is the only other place where it's used.

ok gilles@


# 1.367 25-Sep-2012 eric

make const arguments const, and static functions static.

ok chl@


# 1.366 21-Sep-2012 eric

Do not pass the username to forwards_get() which does not have to care about
this. Instead, set the username on the expand context, and copy it on the
expand nodes as they are inserted.

ok gilles@


# 1.365 21-Sep-2012 eric

wrap expandtree into a "struct expand".

ok gilles@


# 1.364 21-Sep-2012 eric

move struct lka_session definition in lka_session.c

ok gilles@


# 1.363 21-Sep-2012 eric

Add a log_envelope() function that log envelope status in a uniform way.
It automagically adds an rcpt=<user@domain> field if "dest" differs from
the original "rcpt". The function takes an "extra" parameter that allows
to add some specific info depending on the context.

ok gilles@


# 1.362 21-Sep-2012 eric

Move ruleset_match() prototype to smtpd.h and make the envelope const.
Adapt a lot of functions in chain to use const args where required.

ok gilles@


# 1.361 20-Sep-2012 eric

constify parameters that are supposed to be const.

ok gilles@


# 1.360 19-Sep-2012 eric

Remove DF_ENQUEUE flag. It is mostly unused and logically broken.
Ignore it in existing envelopes until it gets completely dropped.
Change "smtpctl show queue" to display the address family of the
envelope source instead of the ENQUEUE flag.

ok gilles@


# 1.359 19-Sep-2012 eric

remove IS_RELAY and IS_MAILBOX macros.

ok gilles@


# 1.358 19-Sep-2012 eric

Remove aliases_exists() and aliases_virtual_exists(). The corresponding
*_get() functions can be called directly.

ok gilles@


# 1.357 19-Sep-2012 eric

start cleaning the expansion code:

- change expandtree_* prefix to expand_ for better readability and
because the structure might change at some point
- rename <>_free_nodes() to <>_free()
- remove unused <>_remove_node()
- refcounting has no purpose at all; just remove it as well as the
decrement/increment functions, and replace the latter with <>_insert
- expandnode flags is only used to know if it's been processed or not,
don't make it a flag but a simple field with clear name.

ok gilles@ chl@


# 1.356 18-Sep-2012 eric

- add xmemdup() helper.
- remove useless block in switch.

ok gilles@


# 1.355 18-Sep-2012 eric

simple lka cleanups:

- fix lka* function prototypes in smtpd.h
- make static functions static
- merge lka_session_init() into lka_session()
- make lka_session.c use tree.c to store sessions

ok gilles@


# 1.354 18-Sep-2012 eric

this structure is not useful and ill-named. remove it.

ok gilles@


# 1.353 18-Sep-2012 eric

remove C_NET. it's not used and there is no plan for it at the moment.

ok gilles@


# 1.352 17-Sep-2012 eric

Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.

While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.

ok gilles@ chl@


# 1.351 16-Sep-2012 chl

now that log_imsg() is only used in smtpd.c, set it as static.

ok gilles@


# 1.350 16-Sep-2012 chl

silent warnings

reported by ajacoutot@

ok gilles@ ajacoutot@


# 1.349 16-Sep-2012 gilles

replace BSD-licensed mkdir_p() with ISC-licensed mkdirs(), this allows us
to avoid a dual-licensed util.c for no reason

ok chl@


# 1.348 14-Sep-2012 eric

Remove s_ssl from the smtp session since it is duplicated in the io struct.
Change ssl_session_init to ssl_smtp_init and make it simpler: only create
an SSL* from the SSL_CTX* passed as parameter, so it does not have to know
about the struct session itself. Kill some dead prototypes while there.

ok chl@ gilles@


# 1.347 11-Sep-2012 eric

Rework the scheduler internals. Fix some scheduling loop issues and
handle envelope scheduling/expiration better.

ok gilles@


# 1.346 01-Sep-2012 gilles

remove unused flag


# 1.345 01-Sep-2012 gilles

- remove crypto_backend
- remove support for encrypted queue, it will be reintroduced later after
pouring more thinking into it

if you had it enabled, flush your queue before updating


# 1.344 30-Aug-2012 chl

change crypto_setup() prototype to use const char * instead of uint8_t *

while there do some KNF:
- change 8 spaces to tab
- add/remove some missing/extra space after if's

ok gilles@


# 1.343 30-Aug-2012 chl

switch compress_backend to use FILE * instead of file descriptors, like
crypto_backend

ok gilles@


# 1.342 30-Aug-2012 gilles

- import latest aldap.[ch] and ber.[ch] from ypldap
- revive map_ldap.c by updating it to the current API

diff by Mathieu Masson who played puzzle with an oooold changeset of mine,
this import is to let us work on it in tree, it won't work as is.

idea ok eric@ and chl@


# 1.341 29-Aug-2012 gilles

Introduce the crypto_backend API and provide support for... encrypted queue
using the new API. By default, OpenSMTPD does not provide queue encryption,
but it can be enabled with "queue encryption [args]" and will transparently
encrypt/decrypt envelopes/messages as they hit the queue.

By default, it will use Blowfish in CBC mode with a different random IV for
each envelope and message. User provided key is expanded using sha256 but a
different cipher and digest may be specified in smtpd.conf

Queue encryption is compatible with compression and if both options are set
it will do them in correct order and transparently.

tested by chl@, a few users and myself
ok chl@ and I


# 1.340 28-Aug-2012 chl

remove encrypt.c prototypes leftovers

ok gilles@


# 1.339 26-Aug-2012 gilles

- define ZLIB_BUFFER_SIZE instead of hardcoding 8192
- check gzdopen() failure
- call gzclose() whenever a failure occurs after gzdopen()
- simplify slightly some checks in compress/uncompress
- create PATH_TEMPORARY in /var/spool/smtpd, chmod 700, owned by _smtpd
- compress_zlib should use PATH_TEMPORARY instread of /tmp as we're
chrooted and this will otherwise lead to a fatal()

ok chl@


# 1.338 25-Aug-2012 chl

Add compress_backend, allowing compression of messages and envelopes in the queue.
To use it, just add "queue compress" in smtpd.conf. For now, only zlib is used.

lots of feedback from eric@ and gilles@

ok eric@ gilles@


# 1.337 25-Aug-2012 gilles

- add myself to the copyright in control.c, i've done quite a few changes
there in the last few years ;-)
- get rid of availdesc(): getdtablecount() is so much more reliable
- get rid of env->sc_maxconn, we can be much smarter with getdtablecount()
and getdtablesize()
- disable accept when we hit the control process fd reserve
- disable accept when we fail
- enable accept when we're back below the limit

this is not the full fd exhaustion diff, i'll merge changes from relayd
tomorrow, this was only required to get rid of the env->sc_maxconn and
availdesc() mess

"reads alright" eric@


# 1.336 25-Aug-2012 gilles

- stop accepting clients if we hit our fd reserve limit (or if we fail)
- resume if we go below the fd reserve

with feedback and ok eric@


# 1.335 25-Aug-2012 gilles

- offline enqueue does not need to use the user_backend API, it relies on
system users ... use getpwuid() instead of ub->getbyuid()
- since that was the only caller, get rid of user_backend->getbyuid()

this is the first step towards removing the user_backend API and making
user lookups available through the maps API (yes, virtual user support ;)

ok eric@, ok chl@


# 1.334 25-Aug-2012 gilles

- introduce TRACE_PROFILING
- when smtpd starts with -T profiling it will log_trace() some prof. info
- when smtpd starts with -T profstat, it will push them to stats API with
type STAT_TIMESPEC under key profiling.imsg.*

with this diff we can get live profiling of events with a very minimal
overhead :-)

ok chl@, ok eric@


# 1.333 25-Aug-2012 gilles

- introduce struct stat_value
- statistics can now have a type (counter, timestamp, timeval, timespec and
possibly others in the future)
- stat_increment() / stat_decrement() now take an increment/decrement value
and are at the moment only of type counter
- stat_set() now takes a stat_value
- provide helpers to convert raw values to stat_value

ok eric@, ok chl@

while at it fix a rq_queue_dump() call using a bogus timestamp in scheduler
ramqueue.


# 1.332 24-Aug-2012 chl

In envelope ascii dump/load:
- remove loading of evpid.
- don't dump the msgid
- ignore msgid at load
- remove now unused functions ascii_{dump,load}_uint{32,64}_hex()

With inputs from eric@ and gilles@

ok gilles@ eric@


# 1.331 24-Aug-2012 chl

Don't pass struct envelope pointer in queue backend API, instead use envelope id and
an envelope ascii buffer.

ok eric@ gilles@


# 1.330 24-Aug-2012 eric

Remove the rq_host and rq_batch structures from the ramqueue scheduler.
The scheduler should only allow admin to schedule specific envelopes by
id, or msgid. More advanced scheduling (per host/route/whatever) should
be achieved using smtpctl schedule-id and proper filtering on the queue,
or using ad-hoc scheduler backend and tools.

ok gilles@ chl@


# 1.329 21-Aug-2012 eric

Allow smtpd to work as a backup MX, relaying only to MXs with higher
priority in the DNS record. For example:

accept for domain "foo.org" relay backup "mx3.foo.org"

will relay mails for "foo.org" using only hosts with higher priority
(i.e. lower value) than "mx3.foo.org", which is supposed to be the
current server.

If the specified backup MX is not found in the DNS record, relaying
works as normal.

ok gilles@


# 1.328 21-Aug-2012 eric

Re-enable loop detection, but in mta and mda this time.

ok gilles@


# 1.327 20-Aug-2012 gilles

MAX_LINE_SIZE is supposed to define the max length of a SMTP line ...
... but SMTP_LINE_MAX *also* defines it ... with a different value ...
and did I mention both were too small anyway ?

quick fix until we kill one or the other: bump MAX_LINE_SIZE and define
SMTP_LINE_MAX to be MAX_LINE_SIZE. this fixes the immediate issue while
we decide which one bites the dust.

fixes the crashes and "line too long" errors spotted by todd@
ok todd@, ok chl@


# 1.326 19-Aug-2012 chl

coding style: replace all occurences of u_int* with uint*

ok eric@


# 1.325 19-Aug-2012 chl

Kill envelope_{dump,load}_file() and replace them with envelope_{dump,load}_buffer().

with input from eric@

ok eric@


# 1.324 19-Aug-2012 chl

fix an issue where too long lines were not spot properly.

issue reported by todd@

ok eric@


# 1.323 18-Aug-2012 eric

zap struct mta_batch. Only pass ids where needed.

ok gilles@


# 1.322 18-Aug-2012 gilles

- introduce stat_backend, an API for pluggable statistic backends
> statistics are no longer static structures in shared memory
> statistics are only set, smtpd never uses them in its logic
> each statistic is a key/value where key can be any (dynamic) string
- convert all uses of the former API to use the new one
- implement stat_ramstat that keeps non-persistent stats in ram structure

ok eric@, ok chl@


# 1.321 18-Aug-2012 eric

Major update of the mta internals.

Add a mta_route structure which describes a route through which
outgoing mails are to be sent. This structure holds connection
parameters and limits. When an envelope is received in a batch,
the route for it is looked up, and the envelope is added to the
a list of envelope to be sent for this message on that route: a
task. When the batch is closed, each task is added to the list
of tasks for their respective route.

The routes are drained when new work can happen. The route will
create new mta sessions if necessary. When a session is up and
ready, it picks the first pending task on the route if any. In
the other case, it just closes the connection.

Errors on the connection are reported to the route, so that the
route could be flagged as broken. Currently, three errors on a
an attempt to open a route is reported as a failure for all pen-
ding tasks.

ok gilles@


# 1.320 10-Aug-2012 eric

Move mta and smtp specific defines into their own files.
Some formatting cleanups while there.

ok gilles@


# 1.319 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.318 09-Aug-2012 eric

remove unused function and prototypes


# 1.317 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.316 08-Aug-2012 eric

remove useless defines

ok gilles@ chl@


# 1.315 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


# 1.314 07-Aug-2012 eric

Implement a set of tree_* functions for storing arbitrary pointers in splay
trees with uint64_t keys. Also add x{m,c}alloc and xstrdup helpers.

ok gilles@


# 1.313 29-Jul-2012 gilles

- introduce xlowercase() and allow lowercase() to fail gracefully
- replace all calls to lowercase() with calls to xlowercase()
- in the format string expansion, lowercase() all formats

we will have to reassess all calls to xlowercase() even though it has never
triggered as far as I know, we can probably gracefully fail some of them.
right now we're just keeping former behaviour.

this commit fixes issue reported by Hugo Osvaldo Barrera where a %u format
could lead to a delivery failure (ie: GILLES@openbsd.org should be expanded
to gilles, not GILLES ... only for local deliveries).

ok chl@ on the idea, ok eric@ on the diff


# 1.312 29-Jul-2012 eric

get rid of A_INVALID.
little code cleanup while here.

ok gilles@


# 1.311 29-Jul-2012 eric

remove the session tree from the global env and move it to mta_session.c,
along with mta_relay and mta_session definition.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.310 12-Jul-2012 chl

add support for maildir tagging/folders.

ok gilles@
ok eric@ on previous versions of this patch


# 1.309 10-Jul-2012 chl

backout the:
- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define

but keep the:
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

ok eric@ gilles@


# 1.308 10-Jul-2012 chl

accept address literal for the recipient domain.
while there, change valid_{local,domain}part() prototypes to use const char *.

with input from gilles@ and eric@

ok gilles@ eric@


# 1.307 10-Jul-2012 gilles

- simplify the scheduler loop logic further, it is ridiculously simple now
and I don't think we can do much better (at that level) :-p
- always break out of the handler after processing an envelope, this will
avoid a busy scheduler from not getting a chance to handle SIGTERM/SIGINT
YES we can now ctrl-c a maaaaad scheduler !

ok eric@, ok chl@


# 1.306 09-Jul-2012 gilles

- introduce log_trace(TRACE_SCHEDULER, ...)
- simplify a tiny tiny bit the scheduler loop
- no functional change (yet)


# 1.305 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.304 09-Jul-2012 gilles

first step of simplifying fsqueue:

- remove the /envelopes subdirectory, envelopes are at the same level than
the message file
- kill PATH_ENVELOPES define
- reduce the number of buckets from 0xfff to 0xff, this avoid performances
of the queue to decrease when we start having tons of buckets

this diff introduces a change to the queue layout, you will want to empty
your queue before updating. more cleanup to come

ok eric@, ok chl@


# 1.303 08-Jul-2012 chl

remove enum queue_kind from queue_fsqueue.c.
incoming messages are now always stored in /incoming, whatever the queue_backend is.
remove QOP_FD_RW and fsqueue_message_fd_rw().
while there check return value of generated paths before calling rmtree()

with advice from gilles@ and eric@

ok gilles@ eric@


# 1.302 02-Jul-2012 eric

Lookup queue and scheduler backends by name, rather than enum.
Add a command-line option to specify the backend to use at runtime.

ok gilles@


# 1.301 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


# 1.300 17-Jun-2012 gilles

- introduce struct scheduler_info and the scheduler_info() function to fill
a struct scheduler_info given a struct envelope
- adapt the scheduler API and the scheduler_ramqueue backend to use the new
struct scheduler_info instead of a struct envelope

idea discussed with eric@ and chl@, mechanical diff, no functional change


# 1.299 14-Jun-2012 gilles

- rename filter.h -> filter_api.h to be consistent with upcoming changes


# 1.298 03-Jun-2012 eric

Do not store the envelope id within the envelope, only the message id.
Make sure existing envelopes can be properly loaded.

ok chl@ gilles@


# 1.297 01-Jun-2012 chl

remove unused fields

ok eric@


# 1.296 01-Jun-2012 eric

move envelope dump/load functions to envelope.c

ok gilles@


# 1.295 29-May-2012 gilles

- introduce map_static.c as a backend to static maps in parse.y, this has
the benefit that we no longer have two code paths whenever we deal with
maps, we can always use the backend mechanism.

I have not plugged this in yet, I'll do it in a later commit, just get it
out of my sandbox


# 1.294 29-May-2012 gilles

- introduce text_to_relayhost() which converts an url into a relayhost.
urls are of the form: [schema://]host[:ip]

not used, yet other commits are following ;-)


# 1.293 13-May-2012 gilles

- cleanup parse.y by removing lots of code that should not have been there,
but in ruleset.c and util.c instead.

- introduce the new map_compare() map API call to allow iterating over keys
and comparing them with provided key using provided function. this allows
checking a partial key in a key set, very useful for comparing an address
to a set of netmask.

- introduce new map kind K_NETADDR
- implement K_NETADDR for map_db and map_stdio
- teach ruleset checking how to use the map_compare() with K_NETADDR

we can now do the following:

map "srcaddr" source plain "/etc/mail/srcaddr.txt"

accept from map srcaddr for domain "openbsd.org" [...]


# 1.292 12-May-2012 gilles

- remove unused sources S_EXT, S_DYN and S_EXT from enum map_src
- continue simplification of parse.y
- remove "for network", if we ever need it we can reimport, probably no
one knows of that undocumented strange feature ;-)
- change syntax for virtual domains configuration:

accept for virtual vmap [...] <- wrong
accept for virtual map vmap [...] <- right

the reason for this change is that we will soon implement relay rules
through maps and that keeping that syntax would make it inconsistent
with the other rules.

- update man pages for makemap and smtpd.conf to reflect changes

ok eric@, looks ok chl@


# 1.291 12-May-2012 gilles

- simplify a bit maps by removing fields which are still unused years
after the initial ambitious implementation: byebye map type & map flags

- simplify a bit parse.y by removing assignations to these otherwise unused
fields

- remove the DNS map source, it may be a good idea, but we can just add it
when we plan to implement it (if we do)

- make the { } options in map declaration, it's been annoying me for a long
time now, this allows the following to work:

map "foobar" source plain "/etc/mail/foobar"

- update smtpd.conf.5 accordingly ;-)


# 1.290 12-May-2012 eric

Update the internal mta implementation so that a session now has a
list of messages to send to the remote smtp server over the same
connection. It's not currently used as the scheduler/runner is not
aware of this yet, and the imsg protocol would need to be updated.

ok gilles@


# 1.289 12-May-2012 gilles

- rename all occurences of K_SECRET to K_CREDENTIALS
- rename all occurences of struct map_secret to map_credentials
- do not fatal if the credentials map has disappeared, instead make the
auth fail with a lookup failure. the mail will be temporary failed so
it stays in queue until admin fixes smtpd.conf, removes mail, or lets
it expires


# 1.288 11-May-2012 eric

split the session logic off mta.c into mta_session.c

ok gilles@


# 1.287 07-Mar-2012 gilles

various reliability fixes:

- prevent queue_fsqueue from fatal() when it hits an ENOENT, it can happen
- change a bit the scheduler API to simplify it, fix runner accordingly

- we can't remove msg/batch from ramqueue while envelope is offloaded or
it will cause a double, instead we add refcnt to both msg/batch and
only free them when it hits 0


Revision tags: OPENBSD_5_1_BASE
# 1.286 31-Jan-2012 gilles

fix an issue observed this week-end while flooding ajacoutot@ :

we keep track of available fd's to prevent scheduling of messages if we
know that we are going to fail. however, since the envelope is not
removed from the scheduler, it will be rescheduled right away leading to
a busy loop in the scheduler. we know flag the mda/mta processes as BUSY
and do not schedule envelopes that target a BUSY process.

also, fix a potential bug that could lead to a use after free when doing
a batch/message/host traversal of schedulable envelopes.

while at it fix misuse of env->sc_opts as env->sc_flags, was not really
causing any issue as the misuse was constant ...


# 1.285 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.284 28-Jan-2012 gilles

add optional display handler to scheduler_backend, if not NULL the handler
will be called for each iteration of the runner

implement a display handler for scheduler_ramqueue to display the entire
ramqueue (hosttree, msgtree and linear queue) in log_debug


# 1.283 28-Jan-2012 eric

remove useless state

ok gilles@


# 1.282 28-Jan-2012 gilles

- introduce the scheduler_backend API
- introduce the scheduler_ramqueue backend
- remove all occurences of ramqueue outside of the ramqueue backend
- teach runner how to use the new API

it is now possible to write custom schedulers !

ok eric@, ok chl@


# 1.281 24-Jan-2012 eric

Add a parameter to the queue backend init() call to specify wether the
call is issued by smtpd or smtpctl. In the latter case, only perform
sanity checks and do not touch directories. A running server no
longer lose its "incoming/" directory each time smtpctl is called...

ok gilles@


# 1.280 18-Jan-2012 chl

Add new filters callbacks for:
- network events (CONNECT/CLOSE)
- commands (QUIT/RSET)

ok gilles@ eric@


# 1.279 13-Jan-2012 eric

queue_message_purge() and queue_message_delete() are actually the same
thing. Remove queue_message_purge() in favor of queue_message_delete
and simplify fsqueue_message_delete() implementation to move the
message dir to purge/

ok gilles@


# 1.278 13-Jan-2012 eric

remove the status field from struct envelope, move it to the smtp
session, and cleanup the DS_* flags.

ok gilles@ chl@


# 1.277 13-Jan-2012 eric

Stop using envelope->status to report delivery outcome to the
runner/queue. Instead, replace IMSG_QUEUE_MESSAGE_UPDATE with three
messages:

- IMSG_QUEUE_DELIVERY_OK
- IMSG_QUEUE_DELIVERY_TEMPFAIL
- IMSG_QUEUE_DELIVERY_PERMFAIL

1) it's less confusing as status is also used by smtp
2) it's easier to see what happens just looking at imsg traces
3) it makes the code path generally easier to follow
4) it's safer because it enforces clear semantics and intent, whereas
the status field is loosely defined and could carry bogus values.

ok gilles@ chl@


# 1.276 12-Jan-2012 eric

use mbox backend for mbox delivery.

ok gilles@


# 1.275 12-Jan-2012 eric

Remove dead code for config reloading for now. It is not functionnal
and confusing.

ok gilles@


# 1.274 12-Jan-2012 eric

remove envelope_get_errormsg() and move envelope_set_errormsg()
to envelope.c

ok gilles@


# 1.273 11-Jan-2012 gilles

remove stateful iteration from ramqueue, if we ever need to reintroduce it
we'll do it, but it isn't used and causes potential bugs

idea by Nathanael Rensel, diff by me, ok eric@


# 1.272 11-Jan-2012 gilles

implement an envelope_ascii API that's not tied to a specific queue_backend
simplify queue_fsqueue


# 1.271 11-Jan-2012 eric

Simplify runner/queue by getting rid of Q_PURGE. Instead, let smtpd
periodically clear the purge/ directory. At init time, the fsqueue
backend simply moves the existing incoming/ dir in purge/ to discard
aborted sessions.

ok gilles@ chl@


# 1.270 11-Jan-2012 eric

remove dead prototype

from Nathanael Rensen

ok gilles@


# 1.269 27-Dec-2011 eric

Q_BOUNCE is not used anymore

ok gilles@


# 1.268 18-Dec-2011 chl

Sync comments with latest cleanup changes

ok eric@


# 1.267 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.266 14-Dec-2011 eric

split auth_backend.c for consistency

ok chl@ gilles@


# 1.265 14-Dec-2011 eric

move show_queue() and related functions from queue_shared.c
to smtpctl.c

ok gilles@


# 1.264 14-Dec-2011 eric

make queue_fsqueue backend consistent with the backend scheme.

ok gilles@


# 1.263 13-Dec-2011 gilles

*finally* make use of certificate authority file if available !

bits from relayd, ok chl@, ok eric@


# 1.262 13-Dec-2011 eric

split user_backend.c into user.c and user_pwd.c to be consistent with the
backend scheme. Also rename USER_GETPWNAM to USER_PWD.

ok chl@ gilles@


# 1.261 13-Dec-2011 gilles

- introduce delivery backend API (delivery.c)
- move each delivery method to it's own delivery backend
- simplify smtpd.c accordingly
- rename A_EXT -> A_MDA since that's what we really do

ok eric@


# 1.260 12-Dec-2011 eric

add a session_enter_state() function to change the state of an smtp
session and allow those state changes to be traced (add traces flags
for upcoming changes while there).

ok chl@ gilles@


# 1.259 12-Dec-2011 chl

remove comments about dead "struct delivery"

"obvious ok" gilles@


# 1.258 11-Dec-2011 eric

utility function for parsing and validating SMTP response lines

ok gilles@


# 1.257 11-Dec-2011 eric

Make the mta code a bit more straightforward:
- fetch the ssl cert earlier on if needed
- skip mta_pickup() when handling the incoming fd

ok gilles@


# 1.256 08-Dec-2011 todd

rename struct user to struct mta_user to avoid namespace conflict elsewhere
ok chl@ & gilles@


# 1.255 28-Nov-2011 chl

fix STATE_COUNT count

ok eric@ gilles@


# 1.254 21-Nov-2011 eric

get rid of the "enqueue/" queue; use "incoming/" instead.

ok gilles@ chl@


# 1.253 16-Nov-2011 eric

remove unused functions

ok gilles@ chl@


# 1.252 16-Nov-2011 eric

Do not unlink an offline message until it has been correctly enqueued.
While there, simplify the offline_enqueue() function by doing all the
sanity checks in the forked process, and remove all fatal(): on error,
the offline message is left untouched in the directory. Also, get rid
of the path_starts_with() check since all paths to offline messages are
now constructed internally.

ok gilles@ chl@


# 1.251 15-Nov-2011 gilles

Qwalk, our API to linearly walk over the persistent queue, did not take the
queue_backend into account and assumed a filesystem with a specific layout.

This commit does plenty of things:

- make qwalk an abstraction in the queue_backend API, and impose queue
drivers to implement qwalk_open(), qwalk() and qwalk_close();

- move previous qwalk_open(), qwalk() and qwalk_close() to the fsqueue
driver since they were fsqueue specific ...

- make qwalk API work with msgid/evpid instead of pathnames since we're
going to use the queue_backend API to load envelopes by evpid anyway;

- makes smtpd use *solely* the queue_backend API when manipulating the
queue. pathnames were removed from smtpd.h and moved into the fsqueue
which means we can now store a queue anywhere ... as long as we write
the ten functions or so required for a queue driver ;-)

ok eric@, ok chl@


# 1.250 14-Nov-2011 chl

when receiving an unexpected imsg, print its name.

with help and ideas from eric@

ok eric@ gilles@


# 1.249 14-Nov-2011 eric

The spool and offline directories are backend-independent, so they
must be created early by smtpd, rather than in fsqueue.

ok gilles@ chl@


# 1.248 07-Nov-2011 eric

Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.

ok gilles@


# 1.247 26-Oct-2011 gilles

- fix smtpctl pause/resume so the ramqueue scheduling is done correctly
- rename IMSG and smtpctl pause/resume parameters
- update man page

tested by me, ok chl@, eric@


# 1.246 23-Oct-2011 eric

a few important fixes:

- use correct endianness when dumping/loading port
- use the right flag set when dumping/loading flags
- keep and use the authmap name when needed, rather than an id that
might change when smtpd is restarted
- dump/load the authmap name with the envelope
- remove the rule struct from rq_batch as only the relay info is useful

ok gilles@


# 1.245 23-Oct-2011 eric

relay_as is not used anuwhere

ok gilles@


# 1.244 23-Oct-2011 gilles

introduce Q_CORRUPT and queue_backend operation to move a message from
schedule queue to corrupt queue upon envelope loading failure.

tested by me, ok eric@


# 1.243 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.242 22-Oct-2011 eric

Add a log_trace() call to toggle logging of specific debugging info in
verbose mode, and an associated -T command line option. Use it for
the imsg traces.

Requested by gilles@ who doesn't like verbose to be too verbose.

ok gilles@ chl@


# 1.241 09-Oct-2011 eric

show messages sent between processes in debug mode

ok gilles@ chl@


# 1.240 19-Sep-2011 chl

Quick fix to avoid fatal() when we receive a line which have a length of exactly 1024.

Better fix comming soon.

Committing on behalf of gilles@


# 1.239 18-Sep-2011 gilles

a single ramqueue message may be shared by many ramqueue envelopes to be
delivered to many ramqueue hosts, therefore storing the rq_host pointer in
the rq_msg envelope is wrong and causes baaaaad behavior.

this commit fixes reliability issues in runner process, experienced and
reported by many


# 1.238 12-Sep-2011 gilles

- introduce filtermask in struct smtpd
- do not forward lines to mfa when FILTER_DATALINE is not set in filtermask

prevents smtpd from handling mails slowly while I'm hacking on filters
support


# 1.237 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


# 1.236 31-Aug-2011 gilles

add support for per-line DATA callbacks, this allows filters to take their
decisions *while* the message is being received by the client.


# 1.235 27-Aug-2011 gilles

typo


# 1.234 27-Aug-2011 gilles

initial support for a session-time filtering API

currently only HELO/EHLO, MAIL, RCPT are supported, however ... I have
voluntarily disabled filters at smtpd.conf level so people don't play with
it until the API has stabilized a bit

discussed with several people in private, no one opposed the feature


# 1.233 17-Aug-2011 gilles

move ramqueue_host pointer from ramqueue_envelope to ramqueue_message.
this allows us to save one pointer from each envelope stored in ram while
still allowing O(1) host lookups by ramqueue_envelope.


# 1.232 17-Aug-2011 gilles

- teach smtpctl remove about the new ramqueue structure
- bonus #1: O(log n) removal of envelopes
- bonus #2: removing all envelopes that have the same msgid works again


# 1.231 17-Aug-2011 gilles

- introduce ramqueue_lookup_{host,message,envelope} to perform lookups in
the new ramqueue structure
- introduce ramqueue_reschedule() and ramqueue_reschedule_envelope() which
to reschedule a message or a specific envelope.

O(n) -> O(log n) \o/


# 1.230 16-Aug-2011 gilles

add a host-tree and an envelope-tree in the ramqueue, they will be used to
improve scheduling and general ramqueue operations. unused yet


Revision tags: OPENBSD_5_0_BASE
# 1.229 21-Jul-2011 gilles

- update smtpctl.8 to reflect reality
- bring back 'smtpctl schedule' and 'smtpctl remove' to life

Things you should know:

The ramqueue data structure is not finished yet and lacks an envelope tree
for evpid lookups. I wanted to wait until I'm done but too many people are
affected by not being able to reschedule envelopes, this is a quick fix.

So right now there's an O(rrible) complexity as both commands will perform
a (possibly aborted) queue scan leading to O(n). I will make that O(log n)
soon.

Also, smtpctl remove no longer supports removing an entire message, I will
fix that very soon too.


# 1.228 20-Jul-2011 eric

Fix reporting of permanent/temporary failures for MX lookups.
Simplify code a bit while there.

ok gilles@


# 1.227 09-Jun-2011 gilles

'relay as' and 'relay via as' rules allow smtpd to rewrite the user part,
the domain part or the entire address of the sender at the SMTP sesssion
level. this is not masquerade but allows smtpd to communicate with hosts
that do a check of SMTP sender fqdn.

sent to tech@, a couple 'no regression' feedbacks


# 1.226 21-May-2011 gilles

remove unused commented structure


# 1.225 21-May-2011 gilles

until now the map_backend API was not really useful for backends that are
not key/val stores. refactored a bit so that smtpd can really take
advantage of backends. preliminary work for ldap support ;-)

no functionnal change


# 1.224 17-May-2011 gilles

introduce new user_backend API for smtpd to lookup the users it wants to
deliver mail to. the only backend supported for now is USER_GETPWNAM and
it is not yet possible to switch to an alternate backend.

yes this means that we're very close from smtpd being able to handle fully
virtual accounts for both incoming and outgoing messages.


# 1.223 17-May-2011 gilles

smtpd now uses an auth_backend API to authenticate users that are allowed
to send mail so they do not necessarily need a local system account.

two backends are provided by default, bsd_auth(3) and getpwnam(3), however
smtpd will only select bsd_auth(3) for the moment and not provide a way to
chose any other backend (that's on purpose ;p).

bye bye authenticate() !


# 1.222 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.221 06-May-2011 eric

move dns session specific structs and prototypes out of smtpd.h.

ok gilles@


# 1.220 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.219 17-Apr-2011 gilles

cleanups, cosmethic changes, functions that should be static are now static
no functionnal change


# 1.218 17-Apr-2011 gilles

remove unused IMSG_ defines


# 1.217 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.216 17-Apr-2011 gilles

no functionnal change, getting rid of deprecated prototypes


# 1.215 15-Apr-2011 gilles

whenever an envelope is reinserted into the ramqueue after a trip to mda or
mta, call runner_reset_events() so runner starts reprocessing ramqueue


# 1.214 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.213 14-Apr-2011 gilles

- implement missing operations for fsqueue:
fsqueue_envelope_create(), fsqueue_message_purge()
- kill deprecated functions in queue_shared.c

At this point fsqueue backend is almost complete, all that is left to do is
to move the qwalk() API inside the queue_backend API, then make sure smtpd
is no longer calling anything queue related directly.


# 1.212 14-Apr-2011 gilles

no functionnal change


# 1.211 14-Apr-2011 gilles

- implement fsqueue_message_create() and fsqueue_message_commit()
- change a few prototypes to allow bounce messages to use the
queue_backend API until it gets merged in
- kill functions of the queue API that have been deprecated


# 1.210 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.209 14-Apr-2011 gilles

smtpd makes too many assumptions about the structure and layout of its
disk-based queue, it makes it near impossible to make changes to it without
editing twenty files... how am i going to implement mongodb support ? :-)

bring a new queue_backend API which hides the details of the disk-based
queue to smtpd. it is not "plugged in" yet and I'm filling the holes.


# 1.208 13-Apr-2011 gilles

following an idea from jacekm@, smtpd now uses a ram-queue instead of doing
a continuous walk on the disk-queue. the implementation differs from what
jacekm@ commited (and I backed out) a while ago in that it uses a queue and
a host tree required for upcoming features.

code will be improved in tree, it requires changes to be done in queue and
bounce API, I just wanted to commit a working version first ...

tested by todd@ and I


# 1.207 02-Apr-2011 eric

add stat counters for the lookup agent

ok gilles@


# 1.206 29-Mar-2011 eric

remove unused code now that reverse lookups are done through asr.

ok gilles@


# 1.205 26-Mar-2011 eric

missing file in previous commit

ok gilles@


# 1.204 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.203 26-Mar-2011 eric

use an index for iterating into the mx list.

ok gilles@


# 1.202 15-Mar-2011 gilles

let smtpd use user-provided Diffie-Hellman parameters for ephemeral key
exchange. if no DH parameters are found, fallback to builtin parameters
as was done until now.

since we now accept user-provided DH parameters, make smtpd more strict
and fatal() if the parameters are bogus.

bump the key size of the DH parameters from 512bits to 1024bits, it might
be bumped further after some more research.

thanks to mikeb@ for his suggestions

diff ok mikeb@ , man ok jmc@


# 1.201 09-Mar-2011 gilles

smtpctl show stats displays inet4/inet6 repartition for incoming sessions


Revision tags: OPENBSD_4_9_BASE
# 1.200 29-Nov-2010 gilles

replace the fork-based-non-blocking-resolver-hack by shiny async resolver
written by eric@. it is still experimental but still better than what we
had earlier so ... we'll improve in tree :)

diff by me with *lots* of help from eric@, tested by todd and I (and a
few people out there)


# 1.199 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.198 24-Nov-2010 todd

add *maxactive stats
"ok and no need to keep them for yourself" gilles@


# 1.197 29-Oct-2010 gilles

smtpd no longer knows a map called "secrets" which holds credentials for
authenticated relaying. one can create many maps holding credentials and
name them however he/she wants, just like any other map.

teach smtpd how to select a credentials map at the rule-level allowing a
setup to relay through the same MX with different credentials depending
on the source.

smtpd.conf.5 updated to reflect changes with help from jmc@


# 1.196 28-Oct-2010 gilles

teach smtpd how to handle per-rule delays for message expiry, this allows
some rules to have a longer expiry delay than the default:

accept for [...] relay expire 8d # will stay 8 days in queue

I added the man page bits so I don't forget but I need to reword it a bit


# 1.195 09-Oct-2010 gilles

backout the "new" queue code commited 4 months ago. it has many good ideas,
is way more optimized than what we had earlier and there's definitely stuff
we want to keep, however it is early optimization that doesn't account for
many features and makes them hard (if not impossible) to write without
ugly workarounds that ruin the purpose of the optimizations.

the backout goes to 30 May's right before the commit and catches up on all
the non-queue related commits that happened since then.

i'll work on reintroducing the ideas from this queue when the basic
features we expect from a MTA are implemented.

suggested on tech@ about a week ago, no objections, several "please make
smtpd move forward" mails from hackers and tech readers.


# 1.194 20-Sep-2010 gilles

- fix a regression caused by latest commit (long story made short: do not
attempt to expand the local delivery buffer when relaying mail, it was
kind of ok before but no longer is)
- use the same buffer for local deliveries to files and commands

tested by jmc@ and I


Revision tags: OPENBSD_4_8_BASE
# 1.193 10-Jun-2010 chl

allow configure queue expiry

with help from jacekm@

ok gilles@ jacekm@


# 1.192 09-Jun-2010 zinovik

switch `ref' data type to int, because it is tested for negative value in
queue_mem_content_unref() function

ok jacekm@, gilles@


# 1.191 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.190 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.189 01-Jun-2010 jacekm

Schedule newly arrived mail immediately, ie. place it at the beginning
of the list of next items to try, or near the beginning if the schedule
contains expired mail, which is of highest priority.


# 1.188 31-May-2010 jacekm

oops


# 1.187 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.186 31-May-2010 chl

imsg_compose_event() return value was never checked. Make it fatal() if needed.

ok jacekm@ gilles@


# 1.185 27-May-2010 gilles

when a rule has two conditions (ie: accept for { domain foo, domain bar } )
expand to two rules each having its own condition rather than one rule
with a tail queue of conditions. this simplifies code a bit and removes a
couple hacks.

basic testing by oga and me


# 1.184 27-May-2010 gilles

struct opt as not used anywhere else, kill it, we can reintroduce it later
if we feel a need for it


# 1.183 27-May-2010 gilles

kill struct opt from struct rule, we don't use it, we don't need it


# 1.182 27-Apr-2010 gilles

this commit enables "plain" as a backend for maps (that means aliases,
virtual AND secrets), adds a description in smtpd.conf.5 and removes a
mention to special map "aliases" which was removed a while ago.

to use plain maps: map "myaliases" { source plain "/etc/mail/aliases" }

code diff was okayd a while ago by jacekm@


# 1.181 27-Apr-2010 gilles

initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead
- introduce map_parse_alias() and map_parse_virtual()
- aliases and virtual code no longer assume db(3) but use the map API which
lets them become backend agnostic AND value-checked. this actually makes
the code simpler by removing all values parsing from aliases.c
- rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the
enum has singular names.
- aliases, virtual and forward now work with an expandtree and deal with
multiple levels of resolving by merging expandtree's

more coming soon ;)


# 1.180 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


# 1.179 21-Apr-2010 gilles

introduce first map parser for maps of kind K_SECRETS !

map_parse_secret() converts a map value into a struct map_secret. lka no
longer needs to do any parsing, it simply calls map_lookup() with kind
K_SECRETS, checks if it returned a !NULL value, and call lka_encode_secret
to safely do the base64 encoding.


# 1.178 21-Apr-2010 gilles

map.c is growing big, split it into three different files:
map.c contains the map API calls as usable by smtpd processes,
map_backend.c contains backend implementations and map_parser.c contains
parser implementations used internally by the map API


# 1.177 21-Apr-2010 gilles

map_lookup() takes an additionnal parameter of type enum map_kind which
will be used to select the appropriate map parser. make sure every call
to map_lookup() is updated. map_lookup() currently ignores the value.


# 1.176 21-Apr-2010 gilles

introduce enum map_kind, the map_parsers array and map_parser_lookup()
which will be used to perform stronger checks on map values. they are
unused yet ...


# 1.175 21-Apr-2010 jacekm

Runner process is just a helper for queue, so tear down its imsg
channels to parent, mda, mta, lka, smtp, and control. This leaves
just the channel to queue, which forwards imsgs on runner's behalf
and redirects any replies back to it.

OK gilles@


# 1.174 20-Apr-2010 jacekm

Kill *2400* lines of code by abstracting common bits of the imsg handlers.


# 1.173 19-Apr-2010 gilles

basic support for SIZE extension, has been sitting in my tree for a month
or so ...

okayd by jacekm@ a while ago


# 1.172 19-Apr-2010 jacekm

Simplify local delivery codepath:
- replace uses of struct batch in the parent with simpler struct delivery.
- replace IMSG_BATCH_* dance with single IMSG_MDA_SESS_NEW.
- make mda assume it delivers to external program over a pipe.
- fork helper process when delivering to maildir or a file.

New feature: upon external mda failure use last line of its output
as an error message.

With input and tests from nicm@.

OK nicm@ gilles@


# 1.171 11-Apr-2010 jacekm

Increase limit on the length of "user" in user@domain.com to a value
higher than specified in rfc. Too many mailers don't conform to it,
and it is harmless as far as I can see.

From Tim van der Molen <tbvdm@xs4all.nl>

OK gilles@


Revision tags: OPENBSD_4_7_BASE
# 1.170 03-Mar-2010 jacekm

tweak mda.c rev. 1.36: eliminate risk of busy waiting for socket
to become writable, and make code more idiomatic.

tested by nicm@

ok gilles@


# 1.169 17-Feb-2010 gilles

the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.

idea discussed with and diff okay jacekm@


# 1.168 10-Jan-2010 gilles

- teach runner how to remove a message from queue given a message id/uid
and assuming message is not in processing/scheduled state
- teach smtpctl how to request message removal from runner

discussed with todd@, idea ok jacekm@


# 1.167 03-Jan-2010 chl

Implement "log verbose" and "log brief" to enable or disable verbose debug
logging on runtime.

Based on claudio@'s work on ripd, ospfd, ospf6d, dvmrpd, ldpd, bgpd.

With help/ideas/testing from gilles@ jacekm@ todd@

ok jacekm@


# 1.166 24-Dec-2009 gilles

kill PATH_RUNQUEUEHIGH and PATH_RUNQUEUELOW, i had great plans for them but
they're still unused months later and there's many ways to achieve having a
set of priorities on envelopes without needing additionnal queues.


# 1.165 14-Dec-2009 jacekm

Tweak the logic behind setting the fd limits so that smtpd is less likely
to get upset by custom soft/hard ulimit settings.

Suggested by todd@


# 1.164 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.163 14-Dec-2009 jacekm

Impose sessions limit on the delivery sessions (mta and mda).


# 1.162 14-Dec-2009 jacekm

Do non-blocking I/O when delivering locally over a pipe.


# 1.161 13-Dec-2009 jacekm

Use safe fd limits in smtp, lka, queue, and control. Removes a
possibility for fd-starvation fatal when under heavy load.


# 1.160 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.159 13-Nov-2009 jacekm

Log FQDN and IP of the server we handed mail to. As a bonus, don't delay
logging of successful deliveries until all MXs were tried, plus add logging
of 5yz replies.

tested by todd@, "reads ok" gilles@


# 1.158 09-Nov-2009 gilles

- add a reference count and flags to struct expand_node
- during expansion, no longer create a new node for each result but try to
lookup for an existing equivalent node and increment its reference count
so that: a) we save on memory, b) we don't need to expand the same users
again and again just because they keep appearing in expansion results.
- while expanding, flag nodes as F_EXPAND_DONE so that we know which nodes
we already processed
- be smarter when expanding, if we have a clue that an iteration has not
brought any new result (because no new nodes were added and all existing
nodes have F_EXPAND_DONE), end expansion and proceed to delivery.
- various small cleanups

discussed with jacekm@ yesterday, rebuild aliases db, make clean


# 1.157 08-Nov-2009 gilles

add an alias_to_expand_node() function and use it in aliases.c


# 1.156 08-Nov-2009 gilles

rework a bit expansion and data structures involved in the expansion so we
no longer have a direct mapping between structures saved in aliases/virtual
db and structures used at runtime during expansion.

side effects ? struct alias is smaller, databases are smaller and it is no
longer necessary to rebuild aliases/virtual databases each time jacekm@ or
I make changes to some obscure structure used indirectely during expansion

rebuild databases, flush queues, make clean


# 1.155 08-Nov-2009 gilles

- make aliases expansion use a rb tree instead of a tail queue, the code
doesn't take advantage of the new structure yet, but this was a needed
change for upcoming improvements.
- introduce aliasestree_{lookup,insert,remove} to the aliases api
- rename queue_generate_id() to generate_uid() and move it to utils.c as
it is used all over the place and not only in queue

tree idea discussed with jacekm@, if you update rebuild aliases db, make
clean and flush queue


# 1.154 08-Nov-2009 gilles

first commit of a serie to cleanup, simplify and improve aliases resolution
which is probably the most complex code in smtpd right now. no longer use a
single list to hold aliases to be resolved and resolved aliases, and do not
use struct alias to hold resolved aliases. instead use a delivery list that
is a list of struct path, and populate it with resolved aliases.

idea discussed with jacekm@, this needs some testing to make sure it does
not introduce a regression with aliases. flush your queue and make clean.


# 1.153 05-Nov-2009 gilles

- move a couple prototypes in smtpd.h
- remove prototypes from deprecated functions


# 1.152 03-Nov-2009 gilles

teach makemap how to build a set, which is a map containing only keys.
smtpd is now capable of looking primary domains at runtime in a set, which
means that the following becomes possible:

map "primary" { source db "/etc/mail/primary.db" }
accept for domain map "primary" deliver to mbox

while at it fix a couple bugs in the aliases resolution path which caused
recipients to bounce if a ruleset did not have an "accept for local" rule

"diff reads good" jacekm@, flush queue & make clean


# 1.151 03-Nov-2009 gilles

this commit removes the hardcoded special "aliases" map and brings support
for multiple aliases maps that can be attached at the rule level. with it,
you can for example define different aliases maps for different domains or
different aliases maps for the same domain depending on the client source:

map "localiases" { source db "/etc/mail/localiases.db" }
map "netaliases" { source db "/etc/mail/netaliases.db" }

accept from 192.168.0.0/16 for local alias "localiases" deliver to mbox
accept from all for local alias "netaliases" deliver to mbox

idea discussed with jacekm@ and various other hackers, diff contains some
bug fixes too which were not part of the original diff. man page follows
very shortly ... make clean & flush queue !


# 1.150 03-Nov-2009 gilles

- remove a useless member of struct cond
- have virtual related functions take a map id instead of a map
- shrink a tiny bit ruleset matching
- add missing lka_resolve_path() call in aliases resolution leading to
issues spotted by nicm@


# 1.149 19-Oct-2009 gilles

currently, smtpd is capable of having multiple listeners with different
options but they will all share the same ruleset. this means that there
is no way to have a rule apply to a session established on one listener
but not applied on another.

this commit brings initial support for tagging listeners and having the
rules able to match these specific listeners. The following will define
a rule which will only apply to interfaces tagged as "mynet":

listen on lo0 # implicit lo0 tag
listen on fxp0 tag mynet
listen on fxp1 tag mynet

accept on mynet for domain "example.org" deliver to mbox


# 1.148 19-Oct-2009 gilles

users within virtual domains do not necessarily map to a real user account,
teach smtpd how to deliver using specific user permissions:

accept for virtual map "foo" deliver to maildir "/m/%d/%u" user foo

will deliver mail under /m/domain/user as user foo

idea and initial diff discussed with jacekm@


# 1.147 12-Oct-2009 gilles

- fix a null deref which could happen after a couple iterations of the
aliases/virtual domains resolution code.

- fix a logic bug which caused virtual domains not to be correctly
handled after one iteration of the aliases resolution code.

- introduce a few helper functions to help clean up and simplify the
lka code.

- simplify the IS_EXT/IS_MAILBOX/IS_RELAY macros so they manipulate a
struct path * instead of the mess of dereferences we were passing them.


# 1.146 11-Oct-2009 gilles

implement proper virtual domains instead of faking them on top of primary
domains. this means that:

- virtual domains no longer deliver to a local user when not told to
- they no longer attempt to resolve aliases when not told to
- they no longer need an explicit rule in smtpd.conf for EACH domain
- the "virtual" map is no longer hardcoded
- smtpd no longer needs a restart to support a new domain

instead we introduce the: accept for virtual map "mapname" [...] syntax
which refers to a map that can be manipulated at runtime.

idea discussed and okayd with jacekm@


# 1.145 07-Oct-2009 gilles

currently both mfa and lka perform ruleset matching for their own purposes.
make lka the only caller of ruleset_match(), mfa request match through imsg
which will shrink its code and help me implement virtual domains properly.

idea discussed with jacekm@


# 1.144 23-Sep-2009 jacekm

Plug memleak.


# 1.143 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.142 12-Sep-2009 jacekm

Simplify line len checking: use one limit for all SMTP exchanges.
This is not as strict as various RFCs want it, but we can make it
more granular later. For now, let all mails flow by using the
maximum of all limits found in the RFCs.
ok gilles@


# 1.141 12-Sep-2009 gilles

cmdlinetoolong stat was incremented at the wrong place, fix


# 1.140 12-Sep-2009 gilles

- fix a compile time warning
- add a new stats counter to distinguish between command lines which
exceeded the limit and data lines which exceeded the limits


# 1.139 04-Sep-2009 jacekm

Major mda update:
- Fix: check external mda / mail.local exit code.
- Fix: check maildir rename(2) return code.
- Fix: check read(2) and write(2) return codes.
- Fix: in parent, batchp->env was not set to the env of the current process.
- Fix: clean file in tmp if maildir delivery fails.
- Fix: mark message as temporarily failed upon start, unmark upon sucessful
delivery. (safe default)
- Fix: kill all message drops, aka. PERMFAILUREs, with one exception: when the
local user no longer exists.
- Cleanup: store.c is merged with its only user, mda.c
- Feature: in parent, child_add now returns pointer to the new child struct.
This is used to store and later access child->mda_batch member in order to
associate children with their batches.
- Feature: in parent, external mda / mail.local will timeout after 5 minutes.


# 1.138 02-Sep-2009 jacekm

Include mbox write errors in "show stats". Suggested by gilles.


# 1.137 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.136 27-Aug-2009 jacekm

getpwnam failure that results in setting errno could confuse the
check for non-existent ~/.forward, so make the check more robust;
fix a fd leak under rare circumstances; use secure_file for
testing .forward file security.


# 1.135 07-Aug-2009 gilles

wrap auth_userokay in a new function authenticate_user() and make sure
that only authenticate.c knows about bsd_auth, no functionnal change.


# 1.134 06-Aug-2009 gilles

- change all occurences of T_DAEMON_BATCH,MESSAGE to T_BOUNCE_BATCH/MESSAGE
- make sure T_BOUNCE_MESSAGE is no longer OR-ed to T_MDA/MTA_MESSAGE
- define F_MESSAGE_BOUNCE flag and make sure bounce sessions set it
- teach smtpctl show queue how to recognize a bounce message


# 1.133 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.132 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.131 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.130 28-Jul-2009 gilles

introduce daemon_record_message() and needed glue in queue_shared.c to
atomically create a mailer daemon out of a message. it is unreferenced
for now, this commit makes no functional change.


Revision tags: OPENBSD_4_6_BASE
# 1.129 26-Jun-2009 okan

locally define nitems() macro, #ifndef'd.

"please commit" gilles@ jacekm@


# 1.128 06-Jun-2009 pyr

Get ready for including imsg.h from a lib, when it comes along.


# 1.127 06-Jun-2009 pyr

Sync with relayd:
Stop pushing event handling in the imsg framework.
Instead, provide a small glue layer on top of both imsg and libevent.
This finally clearly separates event handling and imsg construction.

Sidetrack bonus: remove the mega-ugly hack of having a dummy imsg_event_add
stub in smtpctl.
ok jaceckm@


# 1.126 05-Jun-2009 pyr

make smtpd's imsg lib ready, just like relayd and ospfd.
ok gilles@, jacekm@


# 1.125 05-Jun-2009 pyr

Destroy gilles' fantasy function.
ok by a desillusionned gilles@


# 1.124 03-Jun-2009 jacekm

simplify struct batch; ok gilles@


# 1.123 03-Jun-2009 gilles

rename sc_config to sc_conffile since that's what this field is about, it
will prevent a confusion with sc_config which will be a pointer to the
actual configuration.


# 1.122 02-Jun-2009 gilles

make env->sc_listeners and env->sc_ssl pointers, one step further toward
configuration reloading without killing active sessions; ok jacekm@


# 1.121 01-Jun-2009 deraadt

No need for save_getpwuid and such functions which call endpwent.
endpwent is not needed unless setpwent (with stayopen = 1) or getpwent
was used. getpwuid/getpwnam do not use getpwent; i think people must
be assuming this. we are going to improve the man pages for this.
ok gilles


# 1.120 30-May-2009 gilles

It is now possible to specify a certificate to use when relaying to another
host which requests client certificates:

accept [...] relay via [...] ssl certificate "mycert"

diff from Josh Elsasser <josh@elsasser.org>, tested and okayed by me with
no change but the addition of status 554 to the state machine to deal with
remote host telling us it doesn't like our certificate.


# 1.119 28-May-2009 jacekm

Log the incoming message size; ok gilles@


# 1.118 27-May-2009 jacekm

After a successful AUTH command completes, reject any further AUTH commands.

ok gilles@


# 1.117 27-May-2009 jacekm

request flood mitigation:
1) each state may have 2 responses sent quickly;
2) more responses are delayed exponentially, up to a defined limit.

Delay count is user visible (smtp.errors.delays).

ok gilles@


# 1.116 25-May-2009 jacekm

merge smtp_listener_setup into its only caller; ok gilles@


# 1.115 24-May-2009 jacekm

Parent process shouldn't be base64-decoding untrusted strings, move
this code to privsep smtp process; ok gilles@


# 1.114 24-May-2009 jacekm

Parent process forks 3 types of processes, track them all in a single tree
using newly introduced child struct.

Manage process titles centrally in struct smtpd.

ok gilles@


# 1.113 24-May-2009 jacekm

Instead of keeping stats private to each process, and querying every
process individually whenever stats need to be fetched, keep stats
in MAP_ANON shared memory allocated by parent.

This means control has direct access to stats and can respond very
quickly without troubling any other daemon processes.

ok gilles@


# 1.112 20-May-2009 gilles

first step towards configuration reload in smtpd, smtpctl reload will parse
the configuration file again and replace current configuration with new one
in all processes. what we don't support yet is graceful restart, clients in
sessions at the moment of the reload will have a temp failure thrown at 'em
which is ok RFC-wise but which we will try to improve anyway.

tested with various setups, "diff reads good" jacekm@


# 1.111 19-May-2009 jacekm

- Don't advertise nor accept STARTTLS command when session is secure.
- Make the condition when STARTTLS and AUTH are advertised & accepted
more readable.

ok gilles@


# 1.110 19-May-2009 jacekm

Do not ever run /usr/sbin/sendmail, it could link to sendmail
interface for a different MTA. Use the binary in /usr/libexec
directly instead.

Based on remark claudio@ made in passing.

ok gilles@


# 1.109 19-May-2009 jacekm

Verify the amount of IMSG payload is exactly as expected; ok gilles@


# 1.108 18-May-2009 jacekm

Complete rework of bufferevent event masking allowing for more
strictness:
- Drop clients attempting command pipelining; protects the daemon
from all kinds of abuse.
- Replace F_EVLOCKED flag with F_WRITEONLY which has cleaner sematics:
when up, session must not be destroyed nor read from, but may be
written to.
- Write callback becomes a central place for enabling EV_READ.
- Delay bufferevent creation until after ssl handshake is completed.

A bunch of session error stats were added to smtpctl's "show stats".
These could help spotting event masking errors in the future.

ok gilles@


# 1.107 09-May-2009 jacekm

give few states more meaningful names; ok gilles@


# 1.106 09-May-2009 jacekm

- New API to handle all DNS query types (A, MX, PTR) asynchronously.

- Improve RFC compliance: CNAMEs are resolved, equal preference MXs
are randomized, relaying via MX that has equal/lower preference
than local server is prevented, decision on when to treat domain
name as implicit MX is better.

ok gilles@


# 1.105 28-Apr-2009 gilles

smtp auth happened to work by luck because delivery to mbox action was the
first action of an enum and we allocated a struct using calloc, but we did
not properly initialize the action for authenticated users.

while at it, change the name of path action flags so that we know at first
sight that they are path related.

this diff fixes the immediate issue but still needs work.
ok jacekm@, "we'll work out a long term solution"


# 1.104 24-Apr-2009 jacekm

Make aliases case-insensitive, issue reported by Daniel Ouelett; ok gilles@


# 1.103 24-Apr-2009 jacekm

use same timeout at each session state, and make use of
bufferevent_settimeout instead of rolling our own; ok gilles@


# 1.102 24-Apr-2009 jacekm

kill unnecessary struct message_recipient; ok gilles@


# 1.101 21-Apr-2009 jacekm

Make /usr/sbin/sendmail not fail due to smtpd being down.

The approach is to save cmdline + stdin in a file under a newly
added directory /var/spool/smtpd/offline (uid 0 gid 0 mode 1777).
Next time daemon starts, it uses information in that directory
to replay sendmail on user's behalf.

ok gilles@


# 1.100 20-Apr-2009 jacekm

Rewrite smtp session timeouts; use evtimer_* from event(3) instead
of regularly walking session tree in search of idle clients. Gives
the smtp process a chance to become idle.

As a bonus, add smtp.sessions.timeout counter to "smtpctl show stats".

ok gilles@


# 1.99 16-Apr-2009 jacekm

Total rewrite of the sendmail interface. Adds support for -t, -v,
and -F cmdline args. Also, date and Message-Id headers are added
when missing.

The main trouble with the current enqueue code is that it requires
dealing with problems in the control process that are already solved
in the smtp process, ie. duplicating a lot of code which interacts
with untrusted clients. This diff solves this by making sendmail
obtain a SMTP socket from smtp via smtpd.sock, and using that socket
to deliver the message. For smtpd it looks as if connection was
made from the network, only difference being the F_MESSAGE_ENQUEUED
message flag, handy when differentation between local and remote
deliveries is wanted.

Most of the features come from the femail program, created by henning@.

Additional testing by Nigel J. Taylor.

ok gilles@, henning@ happy with smtpd using femail code


# 1.98 15-Apr-2009 jacekm

s/ssmtp/smtps/; ok gilles@


# 1.97 09-Apr-2009 jacekm

change syntax of the "listen on" and "relay via" directives:
1) kill the ssmtp keyword in "ssmtp listen on ...";
2) kill the use keyword in "... use certificate foo";
3) tls no longer implicit, user must explicitely use the tls or smtps option.
4) for "relay via", move the tls/smtps options to right after the
port specification; makes it similar to "listen on".

These directives:

ssmtp listen on fxp0 use ceritifate "foo"
accept for all relay via tls "mx.bar.com"

now become:

listen on fxp0 smtps certificate "foo"
accept for all relay via "mx.bar.com" tls

ok gilles@


# 1.96 22-Mar-2009 gilles

fix a bug in the resolution of forward files which would cause usernames
not to be taken into account if they had no ~/.forward file AND were the
result of an alias expansion that expanded to more than one username.

while at it, I spotted another bug where I would check T_MDA_MESSAGE on
the flags field instead of the type field. the bug could cause two MDA
message to end up in the same batch which is no longer valid.


# 1.95 19-Mar-2009 jacekm

make action_type == 0 mean A_INVALID, not A_RELAY; ok gilles@


# 1.94 15-Mar-2009 gilles

since we are going to share code in smtp sessions and mta sessions, we need
to also share the statistics structure, still being worked on


# 1.93 15-Mar-2009 gilles

the mda process no longer uses struct batch as its central structure to
deal with deliveries, it now uses struct session just like mta and smtp
processes. we now keep the mbox and message descriptors in the session,
saving space in struct message which is now as small as we can make it.
While at it, plugged a memory leak and did some cosmethic changes

This was the last planned change to our struct message which means that
later changes will no longer require a queue flush before rebuild.


# 1.92 15-Mar-2009 gilles

save 4 bytes per message by moving the datafp field of struct message to
struct session where it really belongs.


# 1.91 12-Mar-2009 pea

Add new function time_to_text to correctly display the date.
Use it to display the date in received from header and when we
store headers.

ok jacekm@


# 1.90 10-Mar-2009 jacekm

implement basic logging, needs more work; ok gilles@


# 1.89 09-Mar-2009 jacekm

run external mda directly, not via sh -c; this steals addargs() API
from OpenSSH; ok gilles@


# 1.88 09-Mar-2009 jacekm

Drop ALIAS_TEXT, plain maps got implemented in a different way; ok gilles@


# 1.87 09-Mar-2009 gilles

add basic support for outgoing authentication (AUTH PLAIN over ssl) which
can be turned on by adding "enable auth" to a "relay via" rule. this made
me rework the mx resolution so that it is done by the mta process and not
the runner process anymore.


# 1.86 08-Mar-2009 gilles

when operating in enqueue mode, it was easy to make smtpctl fatal() by
writing a small app that sent out of order imsg's. prevent this by use
of a state machine and read event masking.

issue spotted by jacekm@, temporary fix by me. there are ideas around
this, but we want to experiment them a bit and they are low priority.


# 1.85 08-Mar-2009 gilles

shrink struct message a bit by removing a couple fields which are no longer
used and by moving the rcpt count in struct session where it really belongs

while at it, remove some unused splay tree generation in mfa


# 1.84 08-Mar-2009 gilles

~/.forward files handling was fixed recently so that it is the privileged
process that does the opening, this commit does some cleanup, and fixes a
bug I experienced today which was caused by a use-after-free.

I did some testing to make sure a user cannot cause smtpd to deadlock, or
loop, with broken setups (self-referencing forwards/aliases, empty files,
broken files...), but if you are playing with aliases/forwards PLEASE let
me know of any bug you run into.


# 1.83 06-Mar-2009 gilles

missing prototype


# 1.82 03-Mar-2009 gilles

when forwards/aliases expansion fails in an lka session, make sure that mfa
is notified so that the session does not hang


# 1.81 03-Mar-2009 gilles

Fix a long standing issue where ~/.forward files were opened by user _smtpd
causing them not to be handled when a user's homedir is set to mode 0700. I
still need to do some cleanup and make sure it works as it should, but this
diff provides better behavior than what we had.


# 1.80 03-Mar-2009 gilles

fix mbox locking by having it done by mail.local(8) which in turns uses
lockspool(1). this means our mbox delivery follows a code path that has
become almost identical to external mda deliveries. this is the first
of a serie of diffs actually...

lockspool(1) suggestion by deraadt@, mail.local(8) idea by jacekm@, and
fix and testing by me


# 1.79 01-Mar-2009 jacekm

- Refuse delivery to mbox that is a symlink, pipe, chardev, etc. etc.
- Introduce secure_file, based on secure_filename from OpenSSH, it
checks that mbox has right perms, and that path components are
trustworthy, too.

ok gilles@


# 1.78 01-Mar-2009 jacekm

In "smtpctl show stats", break queue.inserts into queue.inserts.remote
and queue.inserts.local; ok gilles@


Revision tags: OPENBSD_4_5_BASE
# 1.77 24-Feb-2009 gilles

teach smtpctl's parser how to deal with parameters that are not necessarily
a token so that it is possible to do: smtpctl schedule <message id/uid>

introduce F_MESSAGE_FORCESCHEDULE which lets the runner schedule a message
even if the retry delay has not been expired.

F_MESSAGE_ENQUEUED is a valid flag for a message and should not cause an\
errx() in smtpctl show queue


# 1.76 23-Feb-2009 gilles

add valid_message_id() and valid_message_uid() which test that a message id
and uid do not look wrong. this was not needed earlier because we only deal
with message id's coming from trusted sources, but smtpctl will soon have a
new feature which requires us to deal with user provided message id's.


# 1.75 22-Feb-2009 jacekm

put repeated inet_ntop calls into new func ss_to_text, which uses
getnameinfo internally; ok gilles@


# 1.74 19-Feb-2009 jacekm

don't let libevent buffer long lines forever; ok gilles@


# 1.73 18-Feb-2009 jacekm

- add basic syntax checking to mfa
- decline source routing at MAIL FROM, strip at RCPT TO

ok gilles@


# 1.72 17-Feb-2009 jacekm

make newaliases read aliases path from smtpd.conf; idea discussed with
gilles@, pyr@ and henning@, diff ok gilles@.


# 1.71 15-Feb-2009 jacekm

If MX query fails due to DNS error, do not attempt more queries; ok gilles@


# 1.70 15-Feb-2009 jacekm

New config.c that allows for process cloning. Done by pyr@ for
relayd at n2k9, and adapted to smtpd; ok gilles@


# 1.69 14-Feb-2009 jacekm

Implement makemap -t and -o, for output type and dest resp.; ok gilles@


# 1.68 30-Jan-2009 gilles

when decreasing ssl related counters, make sure the session was flagged as
F_SECURE. while at it, add "smtp.sessions.aborted" which keeps track of
sessions which were interrupted before completion.


# 1.67 30-Jan-2009 gilles

improve statistics for smtp process. not only collect the current sessions
count, but also the total sessions count, ssmtp sessions (both current and
total) and starttls sessions (both current and total)

# ./smtpctl/smtpctl show stats|grep smtp.sessions
smtp.sessions = 0
smtp.sessions.active = 0
smtp.sessions.ssmtp = 0
smtp.sessions.ssmtp.active = 0
smtp.sessions.starttls = 0
smtp.sessions.starttls.active = 0
#


# 1.66 30-Jan-2009 gilles

clear the F_EVLOCK flag earlier to prevent the error event handler from
being called again with F_EVLOCK set. this fixes a bug where disconnect
after smtpd sends greeting and before entering any command failed to go
into session_destroy().

while at it, rename the "smtp.clients" statistic to "smtp.sessions" and
add counters to struct s_smtp so that I can add ssmtp and starttls with
my next commit ;)


# 1.65 30-Jan-2009 form

Do not break header for messages received via smtp.

look ok gilles@


# 1.64 30-Jan-2009 gilles

bump descriptors limit to the max and set the maximum connections count to
three quarters of that limit (a session typically has 3 descriptors). when
we hit that limit, we stop accepting connections, and when client closes a
session, we start accepting connections again. this prevents us from going
into a session that is likely to fail because of scarce resources.

idea discussed with jacekm@, code mostly ripped from relayd


# 1.63 30-Jan-2009 gilles

fix a very annoying events masking issue which would cause a fatal() to be
hit under certain conditions; while tracking the bug I ran into other bugs
which were kind of related and could cause us to hit a fatal() too.

fix by me, but with lots of testing and investigation with jacekm@,
ok jacekm@


# 1.62 29-Jan-2009 jacekm

Implement "smtpctl show stats"; ok gilles@


# 1.61 29-Jan-2009 gilles

missing prototype for session_respond() in mta, move session_respond()'s
prototype to smtpd.h
spotted and diff from Oleg Safiullin <form@pdp-11.org.ru>


# 1.60 29-Jan-2009 gilles

Received header line was incomplete for mail submitted through the enqueuer
as well as for some outgoing messages, this is fixed now


# 1.59 29-Jan-2009 gilles

initial starttls support in mta, this allows:

accept for domain "openbsd.org" relay via tls "mx.example.org"

to ensure the relaying of mail for whoever@openbsd.org will happen through
a secure tls (STARTTLS) session. failure to establish a tls session will be
considered as a permanent failure. As a side effect:

accept for domain "openbsd.org" relay via ssl "mx.example.org"

can now work as well and ensure that the relaying happens through ssmtp OR
tls, but never through an unsafe channel. no need to specify a port, they
are automatically detected if not specified.

still a work in progress, don't expect that it will work flawlessly.


# 1.58 29-Jan-2009 gilles

bring initial support for SSL in the mta part of smtpd, allowing for:

accept for domain "openbsd.org" relay via ssmtp "mx1.example.org"

to ensure that deliveries for whatever@openbsd.org goes through an SSL session
to mx1.example.org


# 1.57 29-Jan-2009 jacekm

Common queue walking code for smtpd and smtpctl. Kills majority of showqueue.c,
the remaining code was moved to queue_shared.c; ok gilles@


# 1.56 28-Jan-2009 gilles

mta session state belongs to struct session, not struct batch, remove the
state field from struct batch and propagate the change


# 1.55 28-Jan-2009 gilles

everything we need for the event handling dance is in struct session, the
write handler has been changed to set the bufferevent that's in there
rather than the one in struct batch. since struct batch is no longer doing
anything useful for events handling, we can remove many fields of it.


# 1.54 28-Jan-2009 gilles

first steps towards better mta code. currently mta uses struct batch to
store a lot of its session related code, but this is just not right and
this commit starts making mta code aware of struct session. This will
ease the implementation of ssl sessions in mta.

while at it, make mta autodetect port to use if it isn't provided in a
rule but can be derived from a parameter (i.e: "relay via ssmtp ...").


# 1.53 28-Jan-2009 gilles

when pausing listeners, do not simply disable their events as new
clients would still be able to connect. instead, at pause time we
close and remove the listeners, and at resume time we request the
parent to reconfigure all listeners.

discussed with pyr@


# 1.52 28-Jan-2009 jacekm

Make races between queue and runner impossible by implementing the policy:
1) queue never reads /queue.
2) queue writes to /queue only at message injection time.
3) runner does all reading, and all writing apart from 2).

ok gilles@


# 1.51 28-Jan-2009 gilles

bring loop detection support. we handle this with a qmail-like approach which
consists of checking headers for a custom header, but we also count how many
hops the mail went through and use a hard limit (currently set to 100 as was
recommanded by RFC) as a safe-guard.

idea discussed with jacekm@, qmail approach suggested by claudio@ a long time
ago


# 1.50 28-Jan-2009 gilles

move some functions from queue.c to queue_shared.c as they are not only
used by queue process but also by runner, while at it change the prototype
of queue_open_message_file() so it takes the message id and not a batch,
runner process requires the decriptor before it even starts building a
batch.


# 1.49 28-Jan-2009 gilles

add a struct path to struct message so that we can keep track of the RCPT
provided recipient even after aliases/forwards expansion, we'll need this
for loop detection.

message id and uid being MAXPATHLEN long is a waste, define MAX_ID_SIZE
which is currently set to 64 (but can probably be further reduced) and
make sure that structures and the few strlcpy's use the right define.

original idea by jacekm@ a while ago


# 1.48 27-Jan-2009 gilles

first bricks of enqueue code which allows smtpctl to submit mail to queue
without "talking" smtp to listeners. currently, a big part of the server
side code is done (and requires a cleanup), next step is to get it usable
properly from a mail user agent.


# 1.47 26-Jan-2009 gilles

move some queue related functions that are needed outside of smtpd to the
sharedqueue.c file, smtpctl cannot link queue.o without creating a mess
otherwise. while at it, move some prototypes to smtpd.h as they will be
needed by enqueue code


# 1.46 14-Jan-2009 gilles

live testing shows that some clients will not even send EHLO if banner does
not contain ESMTP. Now that we support some extensions, let's just say that
we are ESMTP ...


# 1.45 08-Jan-2009 jacekm

ensure getpwnam is always followed by endpwent; ok gilles@ henning@


# 1.44 04-Jan-2009 gilles

- smtp can now pause/resume the accepting of incoming messages
- smtpctl recognizes "pause incoming" and "resume incoming"
- setup imsg communication between control process and smtp process


# 1.43 04-Jan-2009 gilles

- runner is now capable of pausing/resuming the scheduling of deliveries
for both mda and mta batches.
- smtpctl can be used to disable/enable deliveries at runtime using the
pause/resume commands.

ok jacekm@


# 1.42 04-Jan-2009 jacekm

kill F_MESSAGE_EXPIRED; ok gilles@


# 1.41 04-Jan-2009 gilles

When matching a recipient domain to a rule, do not use strcasecmp, but use
new hostname_match() function which recognizes * as a wildcard. We can now
do: accept for domain "*.example.org" to match all subdomains.

idea from Nicholas Marriott <nicholas.marriott@gmail.com>, hostname_match()
from me in place of his fnmatch() calls.

ok jacekm@


# 1.40 04-Jan-2009 gilles

- change name of "masked" member in struct netaddr, it was misleading
- allow "from all" so that the ugly "accept from { 0.0.0.0/0, ::/0 }"
construct becomes a nice looking "accept from all"

ok jacekm@


# 1.39 04-Jan-2009 jacekm

cleanup; ok gilles@


# 1.38 04-Jan-2009 gilles

aliases/forwards expansion was not done correctly and a race could
cause delivery to happen before expansion is over, causing some of
the recipients to never receive the mail. change how the mfa, lka,
queue and smtp processes communicate to ensure smtp never receives
an acknowledgment before ALL expanded envelopes are on disk. While
at it, lka was doing work which belongs in mfa, fix that also.

this is based on an idea from a talk with jacekm@, change not over
but already better than what we had.


# 1.37 27-Dec-2008 jacekm

cleanup; ok gilles@


# 1.36 27-Dec-2008 jacekm

Merge hash() and queue_message_hash() into one func, queue_hash(). Fix callers
to use this interface consistently; ok chl@ gilles@


# 1.35 26-Dec-2008 jacekm

parse.y doesn't allow listen backlog configuration, so "bzero default" is used.
Hardcode it instead: 5 is a popular choice across the tree; ok gilles@


# 1.34 21-Dec-2008 gilles

- AUTH PLAIN may receive credentials as a parameter to AUTH or on a
following line, this commit brings support for the latter which was
not supported yet.
- AUTH LOGIN is now supported, allowing smtp auth support on clients that
do not support AUTH PLAIN (ie: my mobile phone for instance ;)


# 1.33 20-Dec-2008 gilles

- import first bricks of SMTP AUTH support. currently only AUTH PLAIN is
supported, AUTH LOGIN will follow soon. AUTH will only work if a
listen directive has "enable auth" keywords, AND session is safe
(ssmtp or starttls).


# 1.32 19-Dec-2008 gilles

- smtpd handled mbox locking failures as "regular" temporary failures which
is not good at all. As a result, under heavy load messages would be
kept in queue, and delayed for hours just because we failed locking
a few times. This commit makes smtpd distinguish between lock fails
and "regular" temporary fails.
- delivery scheduler will reschedule immediately a message that couldn't be
delivered because of a lock fail. If we fail to lock too many times
we fallback to previous "delay increase" logic.

"looks sane" jacekm@


# 1.31 18-Dec-2008 jacekm

Introduce safe_fclose, which tries to push file to the disk as
quickly as possible; it fails under temporary error conditions,
letting caller react appropriately.

ok gilles@


# 1.30 18-Dec-2008 jacekm

Declarations for functions used only in smtp_session.c were moved
to that file from smtpd.h.

ok gilles@


# 1.29 18-Dec-2008 jacekm

Check fwrite return code at DATA stage.

Add basic line length checking, as required by rfc.

It is no longer required to disable EV_READ upon evbuffer_readline failure.

ok gilles@


# 1.28 17-Dec-2008 jacekm

Introduce /purge, where all msgs scheduled for deletion are put by
queue, and removed from disk by runner.

On startup, clean /incoming by moving msgs within it to /purge.

ok gilles@


# 1.27 13-Dec-2008 jacekm

IMSG_* namespace cleanup.

ok gilles@


# 1.26 13-Dec-2008 jacekm

Declare alias_parse in smtpd.h, and fix callers that pass it wrong
number of arguments.

ok gilles@


# 1.25 12-Dec-2008 jacekm

Format string checking for bsnprintf.

ok gilles@


# 1.24 11-Dec-2008 gilles

- missing prototype


# 1.23 07-Dec-2008 jacekm

Replace evbuffer_add_printf calls with wrapper function, session_respond,
which additionally suffixes <CRLF>, and enables EV_WRITE.

Remove bufferevent_enable(.., EV_WRITE) from session_command and
session_pickup so that EV_WRITE is enabled in exactly one place,
session_respond.

Change some responses slightly to make code fit 80 columns.

ok gilles@


# 1.22 07-Dec-2008 gilles

- getaddrinfo() uses negative values for its error defines, our use of an
u_int8_t to hold the value leads to invalid checking in
runner_batch_resolved(), this lead to a crash in MTA because we
assumed a batch had its mx resolved when it had not. while at it,
be more strict about errors we don't know and fatal(), it should
not happen.

ok jacekm@, ok chl@


# 1.21 06-Dec-2008 weerd

Get rid of anonymous unions. Discussed with and ok gilles@


# 1.20 05-Dec-2008 gilles

- last part of the new queue code: the runner process (unprivileged and
chrooted) is now in charge of doing the scheduling of deliveries,
and the dispatching of messages to MDA and MTA. queue process only
does inserts/updates/removals from the queue and can no longer be
so busy that it delays answers to imsg from smtp server.


# 1.19 04-Dec-2008 cloder

Declare printf-style functions with __attribute__((format(printf,x,x)))
and fix some of the errors caught by this. Part of a general push to
make yyerror() -Wformat clean throughout the tree.


# 1.18 04-Dec-2008 gilles

- fix event masking for DATA and make DATA look more like MAIL and RCPT
with regard to communication with queue process (one state before
sending imsg, another state when imsg has returned). this fixes an
issue that I observed when clients send DATA and content without
even looking at server replies.


# 1.17 03-Dec-2008 gilles

- fix event masking issues in smtp process which could lead to a fatal() if
queue process did not answer fast enough to an imsg. spotted by
Jacek Masiulaniec <jacekm@dobremiasto.net>
- queue layout was mostly to bootstrap the project, it does not behave good
under load, it does complex things to stay in a recoverable state
and it probably didnt do it too well. New queue code is simpler,
smaller and allows for atomic submissions (a mail can never be in a
state where it needs to be recovered). It still needs some work but
works better than previous code, no regression.


# 1.16 25-Nov-2008 gilles

- more prototype moving to smtpd.h


# 1.15 25-Nov-2008 gilles

- move prototype to smtpd.h


# 1.14 25-Nov-2008 gilles

- move prototypes to smtpd.h


# 1.13 25-Nov-2008 gilles

- recent change in parse.y caused htons() to be called twice on the port
provided to "relay via" rules, once in parse.y once in lka.c, fix.
- rename struct address to struct relayhost, introduce struct mxhost which
not only holds the sockaddr_storage, but also additionnal flags we
want forwarded to the mta process.
- propagate the change


# 1.12 25-Nov-2008 gilles

- F_IMSG_SENT is no longer used, kill
suggested by Jacek Masiulaniec <jacekm@dobremiasto.net>


# 1.11 17-Nov-2008 gilles

- until now a client could issue a command from an extension even though it
greeted with helo and not ehlo. introduce session flag F_EHLO and
make sure the session_command() dispatch only looks at extensions
when a session does not have the F_EHLO flag.


# 1.10 17-Nov-2008 gilles

- remove prototypes for the atomic API, we don't use it anymore


# 1.9 11-Nov-2008 gilles

- queue process no longer schedules messages which do not have flag
F_MESSAGE_COMPLETE
- submit recipients to the queue as we read them from RCPT instead of
submiting them all at once when DATA is over. this prevents us
from having to keep a potentially large number of recipients in
memory during the whole session.
- remove all code that dealt with the recipients queue of a message as
it is no longer used.
- several small changes to make sure the server is always in a recoverable
state in case of an unexpected shutdown.


# 1.8 10-Nov-2008 gilles

- open the message file earlier after a successful MAIL command instead of
waiting for the DATA command. this currently has no impact on the
session but is needed for another change that will make submission
of recipients safer with regard to "unexpected shutdowns at bad
timings"


# 1.7 10-Nov-2008 gilles

- define MAX_LINE_SIZE which is the maximum length of a line we allow from
a client. it must be set to the highest value we have from all of
the extensions which are/will be implemented.
- replace all occurences of STRLEN define with MAX_LINE_SIZE, kill STRLEN


# 1.6 10-Nov-2008 chl

rename h_errno field into getaddrinfo_error, to avoid confusion with errno.

h_errno has been obsoleted since the gethostbyname() --> getaddrinfo() replacement.

ok gilles@


# 1.5 10-Nov-2008 chl

fix store_write_header() prototype.

ok gilles@


# 1.4 10-Nov-2008 deraadt

spaces fixed while reading code


# 1.3 10-Nov-2008 gilles

- make READ_BUF_SIZE a power of 2


# 1.2 05-Nov-2008 sobrado

add a few missing id tags; there are a bunch of files, and developers
will probably miss this change when working on more important matters,
so it is probably better to sort them now. there is a risk of losing
the tags if a change needs to be reverted too.

written with excellent advice from jmc@

ok gilles@


# 1.1 01-Nov-2008 gilles

smtpd is a smtp server implementation for OpenBSD. It is a work in progress
which still lacks many features. bringing it in tree will help working on it
more easily.

"at this stage it should go in" henning@, "move ahead" deraadt@